diff --git a/src/monodroid/CMakeLists.txt b/src/monodroid/CMakeLists.txt index ed72fee88f9..0947a0e9bd7 100644 --- a/src/monodroid/CMakeLists.txt +++ b/src/monodroid/CMakeLists.txt @@ -322,6 +322,16 @@ endif() # Compiler and linker flags set(LINK_LIBS "") +# +# -Wformat-nonliteral is disabled as it's not very practical, because we use proxy functions to +# pass formats to the final Android logger functions. The Android functions have attributes that +# cause warnings similar to: +# +# warning G4FD2E6FD: format string is not a string literal [-Wformat-nonliteral] +# +# The warning is, in general, a good practice because the compiler can verify the printf format +# at compile time, but in our case it's not very useful. +# set(LOCAL_COMMON_COMPILER_ARGS -Wall -Wconversion @@ -333,6 +343,7 @@ set(LOCAL_COMMON_COMPILER_ARGS -Wextra -Wformat-security -Wformat=2 + -Wno-format-nonliteral -Wimplicit-fallthrough -Wmisleading-indentation -Wnull-dereference @@ -341,7 +352,6 @@ set(LOCAL_COMMON_COMPILER_ARGS -Wsign-compare -Wtrampolines -Wuninitialized - -fstack-clash-protection -fstrict-flex-arrays=3 ) @@ -370,6 +380,10 @@ endif() set(LOCAL_COMMON_LINKER_ARGS "") if(ANDROID) + list(APPEND LOCAL_COMMON_LINKER_ARGS + -fstack-clash-protection + ) + if (ENABLE_CLANG_ASAN OR ENABLE_CLANG_UBSAN) list(APPEND LOCAL_COMMON_COMPILER_ARGS -fno-omit-frame-pointer diff --git a/src/monodroid/jni/android-system.cc b/src/monodroid/jni/android-system.cc index 2b4c4f5cc0a..68fdcdb5e16 100644 --- a/src/monodroid/jni/android-system.cc +++ b/src/monodroid/jni/android-system.cc @@ -1,29 +1,17 @@ -#include -#include #include -#include +#include +#include #include -#if defined (WINDOWS) -#include -#include -#include -#include -#include -#include -#endif - #include "globals.hh" #include "android-system.hh" -#include "monodroid.h" -#include "monodroid-glue-internal.hh" #include "jni-wrappers.hh" #include "xamarin-app.hh" #include "cpp-util.hh" #include "java-interop-dlfcn.h" #include "java-interop.h" -#if defined (DEBUG) || !defined (ANDROID) +#if defined (DEBUG) namespace xamarin::android::internal { struct BundledProperty { char *name; @@ -32,22 +20,15 @@ namespace xamarin::android::internal { struct BundledProperty *next; }; } -#endif // DEBUG || !ANDROID +#endif // DEBUG using namespace microsoft::java_interop; using namespace xamarin::android; using namespace xamarin::android::internal; -#if defined (DEBUG) || !defined (ANDROID) +#if defined (DEBUG) BundledProperty *AndroidSystem::bundled_properties = nullptr; -#endif // DEBUG || !ANDROID - -#if defined (WINDOWS) -std::mutex AndroidSystem::readdir_mutex; -char *AndroidSystem::libmonoandroid_directory_path = nullptr; -#endif -#if defined (DEBUG) || !defined (ANDROID) BundledProperty* AndroidSystem::lookup_system_property (const char *name) { @@ -58,13 +39,13 @@ AndroidSystem::lookup_system_property (const char *name) } return nullptr; } -#endif // DEBUG || !ANDROID +#endif // DEBUG const char* AndroidSystem::lookup_system_property (const char *name, size_t &value_len) { value_len = 0; -#if defined (DEBUG) || !defined (ANDROID) +#if defined (DEBUG) BundledProperty *p = lookup_system_property (name); if (p != nullptr) { value_len = p->value_len; @@ -102,7 +83,7 @@ AndroidSystem::lookup_system_property (const char *name, size_t &value_len) return nullptr; } -#if defined (DEBUG) || !defined (ANDROID) +#if defined (DEBUG) void AndroidSystem::add_system_property (const char *name, const char *value) { @@ -138,57 +119,8 @@ AndroidSystem::add_system_property (const char *name, const char *value) p->next = bundled_properties; bundled_properties = p; } -#endif // DEBUG || !ANDROID - -#ifndef ANDROID -void -AndroidSystem::monodroid_strreplace (char *buffer, char old_char, char new_char) -{ - if (buffer == nullptr) - return; - while (*buffer != '\0') { - if (*buffer == old_char) - *buffer = new_char; - buffer++; - } -} +#endif // DEBUG -int -AndroidSystem::_monodroid__system_property_get (const char *name, char *sp_value, size_t sp_value_len) -{ - if (!name || !sp_value) - return -1; - - char *env_name = utils.monodroid_strdup_printf ("__XA_%s", name); - monodroid_strreplace (env_name, '.', '_'); - char *env_value = getenv (env_name); - free (env_name); - - size_t env_value_len = env_value ? strlen (env_value) : 0; - if (env_value_len == 0) { - sp_value[0] = '\0'; - return 0; - } - - if (env_value_len >= sp_value_len) - log_warn (LOG_DEFAULT, "System property buffer size too small by %u bytes", env_value_len == sp_value_len ? 1 : env_value_len - sp_value_len); - - // - // sp_value_len includes the terminating nul, avoid a mingw g++ warning about string truncation - // by making the amount of data copied one less than the indicated length. The warning reported - // is: - // - // In function ‘int xamarin::android::internal::AndroidSystem::_monodroid__system_property_get(const char*, char*, size_t)’, - // inlined from ‘int xamarin::android::internal::AndroidSystem::monodroid_get_system_property(const char*, char**)’ at ../../../jni/android-system.cc:243:44: - // ../../../jni/android-system.cc(206,10): warning G20816D19: ‘char* strncpy(char*, const char*, size_t)’ specified bound 93 equals destination size [-Wstringop-truncation] [/home/grendel/vc/xamarin/xamarin-android-worktrees/code-quality-improvements/src/monodroid/monodroid.csproj] - // strncpy (sp_value, env_value, sp_value_len); - // - strncpy (sp_value, env_value, sp_value_len - 2); - sp_value[sp_value_len - 1] = '\0'; - - return static_cast(strlen (sp_value)); -} -#else int AndroidSystem::_monodroid__system_property_get (const char *name, char *sp_value, size_t sp_value_len) { @@ -211,7 +143,6 @@ AndroidSystem::_monodroid__system_property_get (const char *name, char *sp_value return len; } -#endif int AndroidSystem::monodroid_get_system_property (const char *name, dynamic_local_string& value) @@ -263,7 +194,7 @@ AndroidSystem::monodroid_get_system_property (const char *name, char **value) return len; } -#if defined (DEBUG) || !defined (ANDROID) +#if defined (DEBUG) size_t AndroidSystem::_monodroid_get_system_property_from_file (const char *path, char **value) { @@ -299,32 +230,34 @@ AndroidSystem::_monodroid_get_system_property_from_file (const char *path, char } return len; } -#endif +#endif // def DEBUG size_t AndroidSystem::monodroid_get_system_property_from_overrides ([[maybe_unused]] const char *name, [[maybe_unused]] char ** value) { -#if defined (DEBUG) || !defined (ANDROID) - for (size_t oi = 0; oi < MAX_OVERRIDES; ++oi) { - if (override_dirs [oi]) { - std::unique_ptr override_file {utils.path_combine (override_dirs [oi], name)}; - log_info (LOG_DEFAULT, "Trying to get property from %s", override_file.get ()); - size_t result = _monodroid_get_system_property_from_file (override_file.get (), value); - if (result == 0 || value == nullptr || (*value) == nullptr || **value == '\0') { - continue; - } - log_info (LOG_DEFAULT, "Property '%s' from %s has value '%s'.", name, override_dirs [oi], *value); - return result; +#if defined (DEBUG) + for (const char *od : override_dirs) { + if (od == nullptr) { + continue; } + + std::unique_ptr override_file {utils.path_combine (od, name)}; + log_info (LOG_DEFAULT, "Trying to get property from %s", override_file.get ()); + size_t result = _monodroid_get_system_property_from_file (override_file.get (), value); + if (result == 0 || value == nullptr || (*value) == nullptr || **value == '\0') { + continue; + } + log_info (LOG_DEFAULT, "Property '%s' from %s has value '%s'.", name, od, *value); + return result; } -#endif +#endif // def DEBUG return 0; } void AndroidSystem::create_update_dir (char *override_dir) { -#if defined(RELEASE) +#if defined (RELEASE) /* * Don't create .__override__ on Release builds, because Google requires * that pre-loaded apps not create world-writable directories. @@ -335,7 +268,7 @@ AndroidSystem::create_update_dir (char *override_dir) if (log_categories == 0 && monodroid_get_system_property (Debug::DEBUG_MONO_PROFILE_PROPERTY, nullptr) == 0) { return; } -#endif +#endif // def RELEASE override_dirs [0] = override_dir; utils.create_public_directory (override_dir); @@ -352,7 +285,7 @@ AndroidSystem::get_full_dso_path (const char *base_dir, const char *dso_path, dy return const_cast(dso_path); // Absolute path or no base path, can't do much with it path.assign_c (base_dir) - .append (MONODROID_PATH_SEPARATOR) + .append ("/") .append_c (dso_path); return true; @@ -401,7 +334,7 @@ AndroidSystem::load_dso_from_specified_dirs (const char **directories, size_t nu void* AndroidSystem::load_dso_from_app_lib_dirs (const char *name, unsigned int dl_flags) { - return load_dso_from_specified_dirs (static_cast (app_lib_directories), app_lib_directories_size, name, dl_flags); + return load_dso_from_specified_dirs (app_lib_directories.data (), app_lib_directories.size (), name, dl_flags); } void* @@ -409,9 +342,9 @@ AndroidSystem::load_dso_from_override_dirs ([[maybe_unused]] const char *name, [ { #ifdef RELEASE return nullptr; -#else - return load_dso_from_specified_dirs (const_cast (AndroidSystem::override_dirs), AndroidSystem::MAX_OVERRIDES, name, dl_flags); -#endif +#else // def RELEASE + return load_dso_from_specified_dirs (const_cast (AndroidSystem::override_dirs.data ()), AndroidSystem::override_dirs.size (), name, dl_flags); +#endif // ndef RELEASE } void* @@ -439,16 +372,17 @@ AndroidSystem::get_full_dso_path_on_disk (const char *dso_name, dynamic_local_st return false; #ifndef RELEASE - for (size_t i = 0; i < AndroidSystem::MAX_OVERRIDES; i++) { - if (AndroidSystem::override_dirs [i] == nullptr) + for (const char *od : override_dirs) { + if (od == nullptr) continue; - if (get_existing_dso_path_on_disk (AndroidSystem::override_dirs [i], dso_name, path)) + if (get_existing_dso_path_on_disk (od, dso_name, path)) return true; } -#endif - for (size_t i = 0; i < app_lib_directories_size; i++) { - if (get_existing_dso_path_on_disk (app_lib_directories [i], dso_name, path)) +#endif // ndef RELEASE + for (const char *app_lib_dir : app_lib_directories) { + if (get_existing_dso_path_on_disk (app_lib_dir, dso_name, path)) { return true; + } } return false; @@ -459,23 +393,21 @@ AndroidSystem::count_override_assemblies (void) { int c = 0; - for (size_t i = 0; i < MAX_OVERRIDES; ++i) { - monodroid_dir_t *dir; - monodroid_dirent_t *e; - - const char *dir_path = override_dirs [i]; + for (const char *dir_path : override_dirs) { + DIR *dir; + dirent *e; if (dir_path == nullptr || !utils.directory_exists (dir_path)) continue; - if ((dir = utils.monodroid_opendir (dir_path)) == nullptr) + if ((dir = ::opendir (dir_path)) == nullptr) continue; - while ((e = readdir (dir)) != nullptr && e) { + while ((e = ::readdir (dir)) != nullptr && e) { if (utils.monodroid_dirent_hasextension (e, ".dll")) ++c; } - utils.monodroid_closedir (dir); + ::closedir (dir); } return c; @@ -509,7 +441,7 @@ AndroidSystem::get_max_gref_count_from_system (void) if (max < 0) max = std::numeric_limits::max (); if (*e) { - log_warn (LOG_GC, "Unsupported '%s' value '%s'.", Debug::DEBUG_MONO_MAX_GREFC, override.get ()); + log_warn (LOG_GC, "Unsupported '%s' value '%s'.", Debug::DEBUG_MONO_MAX_GREFC.data (), override.get ()); } log_warn (LOG_GC, "Overriding max JNI Global Reference count to %i", max); } @@ -524,7 +456,7 @@ AndroidSystem::get_gref_gc_threshold () return static_cast ((max_gref_count * 90LL) / 100LL); } -#if defined (DEBUG) || !defined (ANDROID) +#if defined (DEBUG) void AndroidSystem::setup_environment (const char *name, const char *value) { @@ -547,13 +479,10 @@ AndroidSystem::setup_environment (const char *name, const char *value) void AndroidSystem::setup_environment_from_override_file (const char *path) { -#if WINDOWS - using read_count_type = unsigned int; -#else using read_count_type = size_t; -#endif - monodroid_stat_t sbuf; - if (utils.monodroid_stat (path, &sbuf) < 0) { + + struct stat sbuf; + if (::stat (path, &sbuf) < 0) { log_warn (LOG_DEFAULT, "Failed to stat the environment override file %s: %s", path, strerror (errno)); return; } @@ -635,7 +564,7 @@ AndroidSystem::setup_environment_from_override_file (const char *path) data_size -= data_width; } } -#endif // DEBUG || !ANDROID +#endif // def DEBUG void AndroidSystem::setup_environment () @@ -655,12 +584,7 @@ AndroidSystem::setup_environment () break; case 'i': -#if !defined (NET) - aotMode = MonoAotMode::MONO_AOT_MODE_LAST; - aot_mode_last_is_interpreter = true; -#else // defined (NET) aotMode = MonoAotMode::MONO_AOT_MODE_INTERP_ONLY; -#endif // !defined (NET) break; default: @@ -700,19 +624,19 @@ AndroidSystem::setup_environment () #if defined (DEBUG) log_info (LOG_DEFAULT, "Setting environment variable '%s' to '%s'", var_name, var_value); -#endif +#endif // def DEBUG if (setenv (var_name, var_value, 1) < 0) log_warn (LOG_DEFAULT, "Failed to set environment variable: %s", strerror (errno)); } -#if defined (DEBUG) || !defined (ANDROID) +#if defined (DEBUG) // TODO: for debug read from file in the override directory named `environment` - for (size_t oi = 0; oi < MAX_OVERRIDES; oi++) { - std::unique_ptr env_override_file {utils.path_combine (override_dirs [oi], OVERRIDE_ENVIRONMENT_FILE_NAME)}; + for (const char *od : override_dirs) { + std::unique_ptr env_override_file {utils.path_combine (od, OVERRIDE_ENVIRONMENT_FILE_NAME.data ())}; if (utils.file_exists (env_override_file.get ())) { setup_environment_from_override_file (env_override_file.get ()); } } -#endif +#endif // def DEBUG } void @@ -730,70 +654,3 @@ AndroidSystem::setup_process_args (jstring_array_wrapper &runtimeApks) { for_each_apk (runtimeApks, static_cast (&AndroidSystem::setup_process_args_apk), nullptr); } - -monodroid_dirent_t* -AndroidSystem::readdir (monodroid_dir_t *dir) -{ -#if defined (WINDOWS) - return readdir_windows (dir); -#else - return ::readdir (dir); -#endif -} - -#if defined (WINDOWS) -struct _wdirent* -AndroidSystem::readdir_windows (_WDIR *dirp) -{ - std::lock_guard lock (readdir_mutex); - errno = 0; - struct _wdirent *entry = _wreaddir (dirp); - - if (entry == nullptr && errno != 0) - return nullptr; - - return entry; -} - -// Returns the directory in which this library was loaded from -char* -AndroidSystem::get_libmonoandroid_directory_path () -{ - wchar_t module_path[MAX_PATH]; - HMODULE module = nullptr; - - if (libmonoandroid_directory_path != nullptr) - return libmonoandroid_directory_path; - - DWORD flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT; - const wchar_t *dir_path = reinterpret_cast(&libmonoandroid_directory_path); - BOOL retval = GetModuleHandleExW (flags, dir_path, &module); - if (!retval) - return nullptr; - - GetModuleFileNameW (module, module_path, sizeof (module_path) / sizeof (module_path[0])); - PathRemoveFileSpecW (module_path); - libmonoandroid_directory_path = utils.utf16_to_utf8 (module_path); - return libmonoandroid_directory_path; -} - -int -AndroidSystem::setenv (const char *name, const char *value, [[maybe_unused]] int overwrite) -{ - wchar_t *wname = utils.utf8_to_utf16 (name); - wchar_t *wvalue = utils.utf8_to_utf16 (value); - - BOOL result = SetEnvironmentVariableW (wname, wvalue); - free (wname); - free (wvalue); - - return result ? 0 : -1; -} - -int -AndroidSystem::symlink (const char *target, const char *linkpath) -{ - return utils.file_copy (target, linkpath); -} -#else -#endif diff --git a/src/monodroid/jni/android-system.hh b/src/monodroid/jni/android-system.hh index 54f0bdd32b9..1b62b8c74ab 100644 --- a/src/monodroid/jni/android-system.hh +++ b/src/monodroid/jni/android-system.hh @@ -2,30 +2,22 @@ #ifndef __ANDROID_SYSTEM_H #define __ANDROID_SYSTEM_H -#include -#include +#include +#include + #include -#include +#include -#ifdef ANDROID +#include #include -#endif -#include "util.hh" -#include "cppcompat.hh" #include "xamarin-app.hh" -#include "shared-constants.hh" #include "basic-android-system.hh" #include "strings.hh" #include -#if !defined (ANDROID) -constexpr uint32_t PROP_NAME_MAX = 32; -constexpr uint32_t PROP_VALUE_MAX = 92; -#endif - -constexpr size_t PROPERTY_VALUE_BUFFER_LEN = PROP_VALUE_MAX + 1; +static inline constexpr size_t PROPERTY_VALUE_BUFFER_LEN = PROP_VALUE_MAX + 1; namespace xamarin::android { class jstring_wrapper; @@ -34,22 +26,18 @@ namespace xamarin::android { namespace xamarin::android::internal { -#if defined (DEBUG) || !defined (ANDROID) +#if defined (DEBUG) struct BundledProperty; #endif class AndroidSystem : public BasicAndroidSystem { private: -#if defined (DEBUG) || !defined (ANDROID) - static constexpr char OVERRIDE_ENVIRONMENT_FILE_NAME[] = "environment"; +#if defined (DEBUG) + static constexpr std::string_view OVERRIDE_ENVIRONMENT_FILE_NAME { "environment" }; static constexpr uint32_t OVERRIDE_ENVIRONMENT_FILE_HEADER_SIZE = 22; static BundledProperty *bundled_properties; #endif -#if defined (WINDOWS) - static std::mutex readdir_mutex; - static char *libmonoandroid_directory_path; -#endif public: void setup_environment (); @@ -57,6 +45,17 @@ namespace xamarin::android::internal void create_update_dir (char *override_dir); int monodroid_get_system_property (const char *name, char **value); int monodroid_get_system_property (const char *name, dynamic_local_string& value); + + int monodroid_get_system_property (std::string_view const& name, char **value) noexcept + { + return monodroid_get_system_property (name.data (), value); + } + + int monodroid_get_system_property (std::string_view const& name, dynamic_local_string& value) noexcept + { + return monodroid_get_system_property (name.data (), value); + } + size_t monodroid_get_system_property_from_overrides (const char *name, char ** value); char* get_bundled_app (JNIEnv *env, jstring dir); int count_override_assemblies (); @@ -64,7 +63,6 @@ namespace xamarin::android::internal void* load_dso (const char *path, unsigned int dl_flags, bool skip_exists_check); void* load_dso_from_any_directories (const char *name, unsigned int dl_flags); bool get_full_dso_path_on_disk (const char *dso_name, dynamic_local_string& path); - monodroid_dirent_t* readdir (monodroid_dir_t *dir); long get_max_gref_count () const { @@ -76,9 +74,6 @@ namespace xamarin::android::internal max_gref_count = get_max_gref_count_from_system (); } -#if defined (WINDOWS) - int setenv (const char *name, const char *value, int overwrite); -#endif bool is_assembly_preload_enabled () const { return application_config.uses_assembly_preload; @@ -101,22 +96,13 @@ namespace xamarin::android::internal bool is_interpreter_enabled () const { -#if !defined (NET) - // HACK! See below - return get_mono_aot_mode () == MonoAotMode::MONO_AOT_MODE_LAST && is_aot_mode_last_really_interpreter_mode (); -#else // defined (NET) return get_mono_aot_mode () == MonoAotMode::MONO_AOT_MODE_INTERP_ONLY; -#endif // !defined (NET) } // Hack, see comment for `aot_mode_last_is_interpreter` at the bottom of the class declaration bool is_aot_mode_last_really_interpreter_mode () const { -#if !defined(NET) - return aot_mode_last_is_interpreter; -#else // defined (NET) return false; -#endif // !defined (NET) } void set_running_in_emulator (bool yesno) @@ -125,7 +111,7 @@ namespace xamarin::android::internal } private: -#if defined (DEBUG) || !defined (ANDROID) +#if defined (DEBUG) void add_system_property (const char *name, const char *value); void setup_environment (const char *name, const char *value); void setup_environment_from_override_file (const char *path); @@ -135,7 +121,7 @@ namespace xamarin::android::internal long get_max_gref_count_from_system (); void setup_process_args_apk (const char *apk, size_t index, size_t apk_count, void *user_data); int _monodroid__system_property_get (const char *name, char *sp_value, size_t sp_value_len); -#if defined (DEBUG) || !defined (ANDROID) +#if defined (DEBUG) size_t _monodroid_get_system_property_from_file (const char *path, char **value); #endif bool get_full_dso_path (const char *base_dir, const char *dso_path, dynamic_local_string& path); @@ -144,33 +130,10 @@ namespace xamarin::android::internal void* load_dso_from_override_dirs (const char *name, unsigned int dl_flags); bool get_existing_dso_path_on_disk (const char *base_dir, const char *dso_name, dynamic_local_string& path); -#if defined (WINDOWS) - struct _wdirent* readdir_windows (_WDIR *dirp); - char* get_libmonoandroid_directory_path (); - int symlink (const char *target, const char *linkpath); - -#endif // WINDOWS - -#if !defined (ANDROID) - void monodroid_strreplace (char *buffer, char old_char, char new_char); -#endif // !ANDROID private: long max_gref_count = 0; MonoAotMode aotMode = MonoAotMode::MONO_AOT_MODE_NONE; bool running_in_emulator = false; - -#if !defined (NET) - // This is a hack because of the way Mono currently switches the full interpreter (no JIT) mode. In Mono - // **internal** headers there's an AOT mode macro, `MONO_EE_MODE_INTERP`, whose value is exactly the same as - // MonoAotMode::MONO_AOT_MODE_LAST. However, we use `MonoAotMode::MONO_AOT_MODE_LAST` as a sentinel to indicate - // that we want to use the default Mono AOT/JIT mode and so we can't "overload" it to mean something else for - // the sake of using Mono's internal functionality. Until Mono makes `MONO_EE_MODE_INTERP` part of the public - // `MonoAotMode` enum and its value is not in conflict with the sentinel, we will use this hack. - // - // See also: https://github.com/mono/mono/issues/18893 - // - bool aot_mode_last_is_interpreter = false; -#endif // !defined (NET) }; } #endif // !__ANDROID_SYSTEM_H diff --git a/src/monodroid/jni/application_dso_stub.cc b/src/monodroid/jni/application_dso_stub.cc index 97f554e4c25..bb9a977e8ce 100644 --- a/src/monodroid/jni/application_dso_stub.cc +++ b/src/monodroid/jni/application_dso_stub.cc @@ -8,7 +8,7 @@ // designer on desktop. const uint64_t format_tag = FORMAT_TAG; -#if defined (DEBUG) || !defined (ANDROID) +#if defined (DEBUG) static TypeMapEntry java_to_managed[] = {}; static TypeMapEntry managed_to_java[] = {}; @@ -149,7 +149,7 @@ DSOCacheEntry dso_cache[] = { // // Support for marshal methods // -#if defined (RELEASE) && defined (ANDROID) && defined (NET) +#if defined (RELEASE) MonoImage* assembly_image_cache[] = { nullptr, nullptr, @@ -206,7 +206,7 @@ void xamarin_app_init ([[maybe_unused]] JNIEnv *env, [[maybe_unused]] get_functi { // Dummy } -#endif // def RELEASE && def ANDROID && def NET +#endif // def RELEASE static const JniRemappingIndexMethodEntry some_java_type_one_methods[] = { { diff --git a/src/monodroid/jni/basic-android-system.cc b/src/monodroid/jni/basic-android-system.cc index db163b72206..5a1fae13dea 100644 --- a/src/monodroid/jni/basic-android-system.cc +++ b/src/monodroid/jni/basic-android-system.cc @@ -1,5 +1,3 @@ -#include - #include "basic-android-system.hh" #include "cpp-util.hh" #include "globals.hh" @@ -7,11 +5,6 @@ using namespace xamarin::android; using namespace xamarin::android::internal; -char* BasicAndroidSystem::override_dirs [MAX_OVERRIDES]; -const char **BasicAndroidSystem::app_lib_directories; -size_t BasicAndroidSystem::app_lib_directories_size = 0; -const char* BasicAndroidSystem::built_for_abi_name = nullptr; - void BasicAndroidSystem::detect_embedded_dso_mode (jstring_array_wrapper& appDirs) noexcept { @@ -32,14 +25,21 @@ BasicAndroidSystem::setup_app_library_directories (jstring_array_wrapper& runtim { if (!is_embedded_dso_mode_enabled ()) { log_debug (LOG_DEFAULT, "Setting up for DSO lookup in app data directories"); - BasicAndroidSystem::app_lib_directories_size = 1; - BasicAndroidSystem::app_lib_directories = new const char*[app_lib_directories_size](); + + BasicAndroidSystem::app_lib_directories = std::span (single_app_lib_directory); BasicAndroidSystem::app_lib_directories [0] = utils.strdup_new (appDirs[SharedConstants::APP_DIRS_DATA_DIR_INDEX].get_cstr ()); log_debug (LOG_ASSEMBLY, "Added filesystem DSO lookup location: %s", appDirs[SharedConstants::APP_DIRS_DATA_DIR_INDEX].get_cstr ()); } else { log_debug (LOG_DEFAULT, "Setting up for DSO lookup directly in the APK"); - BasicAndroidSystem::app_lib_directories_size = runtimeApks.get_length (); - BasicAndroidSystem::app_lib_directories = new const char*[app_lib_directories_size](); + + if (have_split_apks) { + // If split apks are used, then we will have just a single app library directory. Don't allocate any memory + // dynamically in this case + BasicAndroidSystem::app_lib_directories = std::span (single_app_lib_directory); + } else { + size_t app_lib_directories_size = have_split_apks ? 1 : runtimeApks.get_length (); + BasicAndroidSystem::app_lib_directories = std::span (new const char*[app_lib_directories_size], app_lib_directories_size); + } unsigned short built_for_cpu = 0, running_on_cpu = 0; unsigned char is64bit = 0; @@ -62,7 +62,7 @@ BasicAndroidSystem::for_each_apk (jstring_array_wrapper &runtimeApks, ForEachApk force_inline void BasicAndroidSystem::add_apk_libdir (const char *apk, size_t &index, const char *abi) noexcept { - abort_unless (index < app_lib_directories_size, "Index out of range"); + abort_unless (index < app_lib_directories.size (), "Index out of range"); app_lib_directories [index] = utils.string_concat (apk, "!/lib/", abi); log_debug (LOG_ASSEMBLY, "Added APK DSO lookup location: %s", app_lib_directories[index]); index++; @@ -88,23 +88,16 @@ BasicAndroidSystem::setup_apk_directories (unsigned short running_on_cpu, jstrin } } - app_lib_directories_size = number_of_added_directories; + if (app_lib_directories.size () == number_of_added_directories) [[likely]] { + return; + } + + abort_unless (number_of_added_directories > 0, "At least a single application lib directory must be added"); + app_lib_directories = app_lib_directories.subspan (0, number_of_added_directories); } char* BasicAndroidSystem::determine_primary_override_dir (jstring_wrapper &home) { - return utils.path_combine (home.get_cstr (), ".__override__"); -} - -const char* -BasicAndroidSystem::get_built_for_abi_name () -{ - if (built_for_abi_name == nullptr) { - unsigned short built_for_cpu = 0, running_on_cpu = 0; - unsigned char is64bit = 0; - _monodroid_detect_cpu_and_architecture (&built_for_cpu, &running_on_cpu, &is64bit); - built_for_abi_name = android_abi_names [built_for_cpu]; - } - return built_for_abi_name; + return utils.path_combine (home.get_cstr (), SharedConstants::OVERRIDE_DIRECTORY_NAME); } diff --git a/src/monodroid/jni/basic-android-system.hh b/src/monodroid/jni/basic-android-system.hh index a12ba47fa1d..9b6f1bc851f 100644 --- a/src/monodroid/jni/basic-android-system.hh +++ b/src/monodroid/jni/basic-android-system.hh @@ -1,8 +1,11 @@ #ifndef __BASIC_ANDROID_SYSTEM_HH #define __BASIC_ANDROID_SYSTEM_HH +#include #include #include +#include +#include #include "cpu-arch.hh" #include "jni-wrappers.hh" @@ -32,45 +35,27 @@ namespace xamarin::android::internal #pragma clang diagnostic pop #endif static constexpr size_t ANDROID_ABI_NAMES_SIZE = sizeof(android_abi_names) / sizeof (android_abi_names[0]); - static const char* built_for_abi_name; public: #ifdef ANDROID64 - static constexpr char SYSTEM_LIB_PATH[] = "/system/lib64"; -#elif ANDROID - static constexpr char SYSTEM_LIB_PATH[] = "/system/lib"; -#elif LINUX_FLATPAK - static constexpr char SYSTEM_LIB_PATH[] = "/app/lib/mono"; -#elif defined (__linux__) || defined (__linux) - static constexpr char SYSTEM_LIB_PATH[] = "/usr/lib"; -#elif APPLE_OS_X - static constexpr char SYSTEM_LIB_PATH[] = "/Library/Frameworks/Xamarin.Android.framework/Versions/Current/lib/xamarin.android/xbuild/Xamarin/Android/lib/host-Darwin"; -#elif WINDOWS - static const char *SYSTEM_LIB_PATH; + static constexpr std::string_view SYSTEM_LIB_PATH { "/system/lib64" }; #else - static constexpr char SYSTEM_LIB_PATH[] = ""; + static constexpr std::string_view SYSTEM_LIB_PATH { "/system/lib" }; #endif - static constexpr size_t MAX_OVERRIDES = 1; - static char* override_dirs [MAX_OVERRIDES]; - static const char **app_lib_directories; - static size_t app_lib_directories_size; - static const char* get_built_for_abi_name (); + inline static std::array override_dirs{}; + + // This optimizes things a little bit. The array is allocated at build time, so we pay no cost for its + // allocation and at run time it allows us to skip dynamic memory allocation. + inline static std::array single_app_lib_directory{}; + inline static std::span app_lib_directories; public: void setup_app_library_directories (jstring_array_wrapper& runtimeApks, jstring_array_wrapper& appDirs, bool have_split_apks); - const char* get_override_dir (size_t index) const - { - if (index >= MAX_OVERRIDES) - return nullptr; - - return override_dirs [index]; - } - void set_override_dir (uint32_t index, const char* dir) { - if (index >= MAX_OVERRIDES) + if (index >= override_dirs.size ()) return; override_dirs [index] = const_cast (dir); diff --git a/src/monodroid/jni/basic-utilities.cc b/src/monodroid/jni/basic-utilities.cc index adf67f7a9c1..a84ec879614 100644 --- a/src/monodroid/jni/basic-utilities.cc +++ b/src/monodroid/jni/basic-utilities.cc @@ -1,11 +1,6 @@ #include -#include -#include - -#ifdef WINDOWS -#include -#include -#endif +#include +#include #include "basic-utilities.hh" #include "logger.hh" @@ -29,7 +24,7 @@ BasicUtilities::path_combine (const char *path1, const char *path2) *ret = '\0'; strncat (ret, path1, len - 1); - strncat (ret, MONODROID_PATH_SEPARATOR, len - 1); + strncat (ret, "/", len - 1); strncat (ret, path2, len - 1); return ret; @@ -38,15 +33,9 @@ BasicUtilities::path_combine (const char *path1, const char *path2) void BasicUtilities::create_public_directory (const char *dir) { -#ifndef WINDOWS mode_t m = umask (0); mkdir (dir, 0777); umask (m); -#else - wchar_t *buffer = utf8_to_utf16 (dir); - _wmkdir (buffer); - free (buffer); -#endif } int @@ -59,12 +48,7 @@ BasicUtilities::create_directory (const char *pathname, mode_t mode) errno = EINVAL; return -1; } -#ifdef WINDOWS - int oldumask; -#else - mode_t oldumask; -#endif - oldumask = umask (022); + mode_t oldumask = umask (022); std::unique_ptr path {strdup_new (pathname)}; int rv, ret = 0; for (char *d = path.get (); d != nullptr && *d; ++d) { @@ -91,36 +75,34 @@ BasicUtilities::create_directory (const char *pathname, mode_t mode) void BasicUtilities::set_world_accessable ([[maybe_unused]] const char *path) { -#ifdef ANDROID int r; - do + do { r = chmod (path, 0664); - while (r == -1 && errno == EINTR); + } while (r == -1 && errno == EINTR); - if (r == -1) + if (r == -1) { log_error (LOG_DEFAULT, "chmod(\"%s\", 0664) failed: %s", path, strerror (errno)); -#endif + } } void BasicUtilities::set_user_executable ([[maybe_unused]] const char *path) { -#ifdef ANDROID int r; do { r = chmod (path, S_IRUSR | S_IWUSR | S_IXUSR); } while (r == -1 && errno == EINTR); - if (r == -1) + if (r == -1) { log_error (LOG_DEFAULT, "chmod(\"%s\") failed: %s", path, strerror (errno)); -#endif + } } bool BasicUtilities::file_exists (const char *file) { - monodroid_stat_t s; - if (monodroid_stat (file, &s) == 0 && (s.st_mode & S_IFMT) == S_IFREG) + struct stat s; + if (::stat (file, &s) == 0 && (s.st_mode & S_IFMT) == S_IFREG) return true; return false; } @@ -132,8 +114,8 @@ BasicUtilities::directory_exists (const char *directory) return false; } - monodroid_stat_t s; - if (monodroid_stat (directory, &s) == 0 && (s.st_mode & S_IFMT) == S_IFDIR) + struct stat s; + if (::stat (directory, &s) == 0 && (s.st_mode & S_IFMT) == S_IFDIR) return true; return false; } @@ -182,36 +164,22 @@ BasicUtilities::file_copy (const char *to, const char *from) bool BasicUtilities::is_path_rooted (const char *path) { - if (path == nullptr) + if (path == nullptr) { return false; -#ifdef WINDOWS - LPCWSTR wpath = utf8_to_utf16 (path); - bool ret = !PathIsRelativeW (wpath); - free (const_cast (reinterpret_cast (wpath))); - return ret; -#else - return path [0] == MONODROID_PATH_SEPARATOR_CHAR; -#endif + } + + return path [0] == '/'; } FILE * BasicUtilities::monodroid_fopen (const char *filename, const char *mode) { FILE *ret; -#ifndef WINDOWS + /* On Unix, both path and system calls are all assumed * to be UTF-8 compliant. */ ret = fopen (filename, mode); -#else - // Convert the path and mode to a UTF-16 and then use the wide variant of fopen - wchar_t *wpath = utf8_to_utf16 (filename); - wchar_t *wmode = utf8_to_utf16 (mode); - - ret = _wfopen (wpath, wmode); - free (wpath); - free (wmode); -#endif // ndef WINDOWS if (ret == nullptr) { log_error (LOG_DEFAULT, "fopen failed for file %s: %s", filename, strerror (errno)); return nullptr; @@ -221,63 +189,19 @@ BasicUtilities::monodroid_fopen (const char *filename, const char *mode) } int -BasicUtilities::monodroid_stat (const char *path, monodroid_stat_t *s) -{ - int result; - -#ifndef WINDOWS - result = stat (path, s); -#else - wchar_t *wpath = utf8_to_utf16 (path); - result = _wstat (wpath, s); - free (wpath); -#endif - - return result; -} - -monodroid_dir_t* -BasicUtilities::monodroid_opendir (const char *filename) -{ -#ifndef WINDOWS - return opendir (filename); -#else - wchar_t *wfilename = utf8_to_utf16 (filename); - monodroid_dir_t *result = _wopendir (wfilename); - free (wfilename); - return result; -#endif -} - -int -BasicUtilities::monodroid_closedir (monodroid_dir_t *dirp) +BasicUtilities::monodroid_dirent_hasextension (dirent *e, const char *extension) { -#ifndef WINDOWS - return closedir (dirp); -#else - return _wclosedir (dirp); -#endif -} - -int -BasicUtilities::monodroid_dirent_hasextension (monodroid_dirent_t *e, const char *extension) -{ -#ifndef WINDOWS return ends_with_slow (e->d_name, extension); -#else - char *mb_dname = utf16_to_utf8 (e->d_name); - int result = ends_with_slow (mb_dname, extension); - free (mb_dname); - return result; -#endif } void BasicUtilities::monodroid_strfreev (char **str_array) { char **orig = str_array; - if (str_array == nullptr) + if (str_array == nullptr) { return; + } + while (*str_array != nullptr){ free (*str_array); str_array++; diff --git a/src/monodroid/jni/basic-utilities.hh b/src/monodroid/jni/basic-utilities.hh index d7b67d83014..3ed41659c91 100644 --- a/src/monodroid/jni/basic-utilities.hh +++ b/src/monodroid/jni/basic-utilities.hh @@ -3,14 +3,13 @@ #include #include -#include -#include #include +#include #include +#include #include #include - #include #include #include @@ -18,7 +17,6 @@ #include "java-interop-util.h" #include "helpers.hh" #include "cpp-util.hh" -#include "platform-compat.hh" #include "strings.hh" namespace xamarin::android @@ -27,10 +25,7 @@ namespace xamarin::android { public: FILE *monodroid_fopen (const char* filename, const char* mode); - int monodroid_stat (const char *path, monodroid_stat_t *s); - monodroid_dir_t *monodroid_opendir (const char *filename); - int monodroid_closedir (monodroid_dir_t *dirp); - int monodroid_dirent_hasextension (monodroid_dirent_t *e, const char *extension); + int monodroid_dirent_hasextension (dirent *e, const char *extension); void monodroid_strfreev (char **str_array); char **monodroid_strsplit (const char *str, const char *delimiter, size_t max_tokens); char *monodroid_strdup_printf (const char *format, ...); @@ -69,7 +64,7 @@ namespace xamarin::android } buf.append (path1, path1_len); - buf.append (MONODROID_PATH_SEPARATOR); + buf.append ("/"); buf.append (path2, path2_len); } @@ -97,12 +92,37 @@ namespace xamarin::android path_combine (buf, path1, path1_len, path2, path2_len); } + char* path_combine (const char *path1, std::string_view const& path2) noexcept + { + return path_combine (path1, path2.data ()); + } + bool ends_with_slow (const char *str, const char *end) { char *p = const_cast (strstr (str, end)); return p != nullptr && p [strlen (end)] == '\0'; } + template + bool ends_with (internal::dynamic_local_string& str, std::string_view const& sv) const noexcept + { + if (str.length () < sv.length ()) { + return false; + } + + return memcmp (str.get () + str.length () - sv.length (), sv.data (), sv.length ()) == 0; + } + + bool ends_with (const char *str, std::string_view const& sv) const noexcept + { + size_t len = strlen (str); + if (len < sv.length ()) { + return false; + } + + return memcmp (str + len - sv.length (), sv.data (), sv.length ()) == 0; + } + template bool ends_with (const char *str, const char (&end)[N]) { @@ -130,7 +150,7 @@ namespace xamarin::android constexpr size_t end_length = N - 1; size_t len = str.length (); - if (XA_UNLIKELY (len < end_length)) { + if (len < end_length) [[unlikely]] { return false; } @@ -143,7 +163,7 @@ namespace xamarin::android constexpr size_t end_length = N - 1; size_t len = str.length (); - if (XA_UNLIKELY (len < end_length)) { + if (len < end_length) [[unlikely]] { return false; } @@ -156,7 +176,7 @@ namespace xamarin::android constexpr size_t end_length = N - 1; size_t len = str.length (); - if (XA_UNLIKELY (len < end_length)) { + if (len < end_length) [[unlikely]] { return false; } @@ -196,7 +216,7 @@ namespace xamarin::android char *strdup_new (const char* s, size_t len) { - if (XA_UNLIKELY (len == 0 || s == nullptr)) { + if (len == 0 || s == nullptr) [[unlikely]] { return nullptr; } @@ -210,7 +230,7 @@ namespace xamarin::android char *strdup_new (const char* s) { - if (XA_UNLIKELY (s == nullptr)) { + if (s == nullptr) [[unlikely]] { return nullptr; } @@ -240,20 +260,7 @@ namespace xamarin::android return ret; } -#if defined (WINDOWS) - /* Those two conversion functions are only properly implemented on Windows - * because that's the only place where they should be useful. - */ - char *utf16_to_utf8 (const wchar_t *widestr) - { - return ::utf16_to_utf8 (widestr); - } - wchar_t *utf8_to_utf16 (const char *mbstr) - { - return ::utf8_to_utf16 (mbstr); - } -#endif // def WINDOWS bool is_path_rooted (const char *path); template @@ -286,11 +293,7 @@ namespace xamarin::android int make_directory (const char *path, [[maybe_unused]] mode_t mode) { -#if WINDOWS - return mkdir (path); -#else - return mkdir (path, mode); -#endif + return ::mkdir (path, mode); } private: diff --git a/src/monodroid/jni/build-info.hh b/src/monodroid/jni/build-info.hh index b91c9e9d0aa..d869deb624e 100644 --- a/src/monodroid/jni/build-info.hh +++ b/src/monodroid/jni/build-info.hh @@ -1,9 +1,8 @@ #if !defined (__BUILD_INFO_HH) #define __BUILD_INFO_HH -#if defined (ANDROID) +#include #include -#endif // def ANDROID namespace xamarin::android::internal { @@ -14,40 +13,28 @@ namespace xamarin::android::internal class BuildInfo final { public: - static constexpr char xa_version[] = XA_VERSION; - static constexpr char date[] = __DATE__; + static inline constexpr std::string_view xa_version { XA_VERSION }; + static inline constexpr std::string_view date { __DATE__ }; - static constexpr char kind[] = + static inline constexpr std::string_view kind { #if defined (DEBUG) - "Debug"; + "Debug" }; #else // ndef DEBUG - "Release"; + "Release" }; #endif - static constexpr char architecture[] = + static inline constexpr std::string_view architecture { #if defined (__aarch64__) - "ARM64"; + "ARM64" }; #elif defined (__arm__) - "ARM32"; + "ARM32" }; #elif defined (__amd64__) || defined (__x86_64__) - "X86_64"; + "X86_64" }; #elif defined (__i386__) - "X86"; + "X86" }; #endif - static constexpr char ndk_version[] = -#if defined (ANDROID) - VERSION_STRING (__NDK_MAJOR__, __NDK_MINOR__, __NDK_BUILD__); -#else // def ANDROID - ""; -#endif // // ndef ANDROID - - static constexpr char ndk_api_level[] = -#if defined (__ANDROID_API__) - API_STRING(__ANDROID_API__); -#else // def __ANDROID_API__ - ""; -#endif // ndef __ANDROID_API__ - }; + static inline constexpr std::string_view ndk_version { VERSION_STRING (__NDK_MAJOR__, __NDK_MINOR__, __NDK_BUILD__) }; + static inline constexpr std::string_view ndk_api_level { API_STRING(__ANDROID_API__) }; }; } #endif // ndef __BUILD_INFO_HH diff --git a/src/monodroid/jni/cpp-util.hh b/src/monodroid/jni/cpp-util.hh index eac76f0625e..4e698660b68 100644 --- a/src/monodroid/jni/cpp-util.hh +++ b/src/monodroid/jni/cpp-util.hh @@ -5,18 +5,12 @@ #include #include #include +#include #include #include - -#if defined (ANDROID) #include -#else -#include -#endif -#include "cppcompat.hh" -#include "platform-compat.hh" #include "helpers.hh" static inline void @@ -25,19 +19,14 @@ do_abort_unless (const char* fmt, ...) va_list ap; va_start (ap, fmt); -#if defined (ANDROID) __android_log_vprint (ANDROID_LOG_FATAL, "monodroid", fmt, ap); -#else // def ANDROID - vfprintf (stderr, fmt, ap); - fprintf (stderr, "\n"); -#endif // ndef ANDROID va_end (ap); xamarin::android::Helpers::abort_application (); } #define abort_unless(_condition_, _fmt_, ...) \ - if (XA_UNLIKELY (!(_condition_))) { \ + if (!(_condition_)) [[unlikely]] { \ do_abort_unless ("%s:%d (%s): " _fmt_, __FILE__, __LINE__, __FUNCTION__, ## __VA_ARGS__); \ } @@ -84,26 +73,8 @@ namespace xamarin::android char _elems[Size]{}; }; - // MinGW 9 on the CI build bots has a bug in the gcc compiler which causes builds to fail with: - // - // error G713F753E: ‘constexpr auto xamarin::android::concat_const(const char (&)[Length]...) [with long long unsigned int ...Length = {15, 7, 5}]’ called in a constant expression - // ... - // /usr/lib/gcc/x86_64-w64-mingw32/9.3-win32/include/c++/array:94:12: note: ‘struct std::array’ has no user-provided default constructor - // struct array - // ^~~~~ - // /usr/lib/gcc/x86_64-w64-mingw32/9.3-win32/include/c++/array:110:56: note: and the implicitly-defined constructor does not initialize ‘char std::array::_M_elems [17]’ - // typename _AT_Type::_Type _M_elems; - // ^~~~~~~~ - // - // thus we need to use this workaround here - // -#if defined (__MINGW32__) && __GNUC__ < 10 - template - using char_array = helper_char_array; -#else template using char_array = std::array; -#endif template constexpr auto concat_const (const char (&...parts)[Length]) @@ -125,6 +96,37 @@ namespace xamarin::android return ret; }; + template + concept StringViewPart = std::is_same_v; + + template + consteval auto concat_string_views (T const&... parts) + { + std::array ret; // lgtm [cpp/paddingbyteinformationdisclosure] the buffer is filled in the loop below + ret[TotalLength] = 0; + + size_t i = 0; + for (std::string_view const& sv : {parts...}) { + for (const char ch : sv) { + ret[i] = ch; + i++; + } + } + + return ret; + } + + consteval size_t calc_size (std::string_view const& sv1) noexcept + { + return sv1.size (); + } + + template + consteval size_t calc_size (std::string_view const& sv1, T const&... other_svs) noexcept + { + return sv1.size () + calc_size (other_svs...); + } + template , int> = 0> constexpr TEnum operator & (TEnum l, TEnum r) noexcept { diff --git a/src/monodroid/jni/cppcompat.hh b/src/monodroid/jni/cppcompat.hh index 1f2c7047b37..a802a2a12c3 100644 --- a/src/monodroid/jni/cppcompat.hh +++ b/src/monodroid/jni/cppcompat.hh @@ -4,22 +4,8 @@ #include -#undef HAVE_WORKING_MUTEX - -// On desktop builds we can include the actual C++ standard library files which declare type traits -// as well as the `lock_guard` and `mutex` classes. However, some versions of MinGW, even though -// they have the required files, do not declare `mutex` because the `gthreads` feature is not -// enabled. Thus the complicated `#if` below. -#if !defined (ANDROID) && (!defined (WINDOWS) || (defined (WINDOWS) && defined (_GLIBCXX_HAS_GTHREADS))) -#define HAVE_WORKING_MUTEX 1 -#endif - // We can't use on Android because it requires linking libc++ into the rutime, see below. -#if !defined (ANDROID) -#include -#include // Also declares `lock_guard` even if it doesn't declare `mutex` -#endif - +// // Android NDK currently provides a build of libc++ which we cannot link into Xamarin.Android runtime because it would // expose libc++ symbols which would conflict with a version of libc++ potentially included in a mixed // native/Xamarin.Android application. @@ -32,7 +18,6 @@ // we can remove this file. namespace std { -#if defined (ANDROID) template class lock_guard { @@ -58,9 +43,7 @@ namespace std private: mutex_type &_mutex; }; -#endif // !def ANDROID -#if !defined (HAVE_WORKING_MUTEX) class mutex { public: @@ -79,7 +62,6 @@ namespace std private: pthread_mutex_t _pmutex = PTHREAD_MUTEX_INITIALIZER; }; -#endif // !def HAVE_WORKING_MUTEX } #endif diff --git a/src/monodroid/jni/cpu-arch-detect.cc b/src/monodroid/jni/cpu-arch-detect.cc index d5d63ebc58e..601de304beb 100644 --- a/src/monodroid/jni/cpu-arch-detect.cc +++ b/src/monodroid/jni/cpu-arch-detect.cc @@ -1,21 +1,12 @@ #include #include -#if __APPLE__ -#include -#include -#include -#elif _WIN32 -#include -#endif - #include "cpp-util.hh" #include "cpu-arch.hh" -#if __ANDROID__ -#define BUF_SIZE 512 - #if __arm__ +static inline constexpr size_t BUF_SIZE = 512; + static int find_in_maps (const char *str) { @@ -42,7 +33,6 @@ detect_houdini () return find_in_maps ("libhoudini"); } #endif -#endif // __ANDROID__ static unsigned char is_64_bit () @@ -50,42 +40,6 @@ is_64_bit () return sizeof (char*) == 8; } -static int -get_built_for_cpu_windows ([[maybe_unused]] unsigned short *built_for_cpu) -{ -#if _WIN32 -#if _M_AMD64 || _M_X64 - *built_for_cpu = CPU_KIND_X86_64; -#elif _M_IX86 - *built_for_cpu = CPU_KIND_X86; -#elif _M_ARM - *built_for_cpu = CPU_KIND_ARM; -#else - *built_for_cpu = CPU_KIND_UNKNOWN; -#endif - return 1; -#else - return 0; -#endif -} - -static int -get_built_for_cpu_apple ([[maybe_unused]] unsigned short *built_for_cpu) -{ -#if __APPLE__ -#if __x86_64__ - *built_for_cpu = CPU_KIND_X86_64; -#elif __i386__ - *built_for_cpu = CPU_KIND_X86; -#else - *built_for_cpu = CPU_KIND_UNKNOWN; -#endif - return 1; -#else - return 0; -#endif -} - static int get_built_for_cpu_android ([[maybe_unused]] unsigned short *built_for_cpu) { @@ -111,76 +65,11 @@ get_built_for_cpu_android ([[maybe_unused]] unsigned short *built_for_cpu) static void get_built_for_cpu (unsigned short *built_for_cpu) { - if (get_built_for_cpu_windows (built_for_cpu)) - return; - - if (get_built_for_cpu_apple (built_for_cpu)) - return; - - if (get_built_for_cpu_android (built_for_cpu)) + if (get_built_for_cpu_android (built_for_cpu)) { return; - - *built_for_cpu = CPU_KIND_UNKNOWN; -} - -static int -get_running_on_cpu_windows ([[maybe_unused]] unsigned short *running_on_cpu) -{ -#if _WIN32 - SYSTEM_INFO si; - - GetSystemInfo (&si); - switch (si.wProcessorArchitecture) { - case PROCESSOR_ARCHITECTURE_AMD64: - *running_on_cpu = CPU_KIND_X86_64; - break; - - case PROCESSOR_ARCHITECTURE_ARM: - *running_on_cpu = CPU_KIND_ARM; - break; - - case PROCESSOR_ARCHITECTURE_INTEL: - *running_on_cpu = CPU_KIND_X86; - break; - - default: - *running_on_cpu = CPU_KIND_UNKNOWN; - break; } - return 1; -#else - return 0; -#endif -} - -static int -get_running_on_cpu_apple ([[maybe_unused]] unsigned short *running_on_cpu) -{ -#if __APPLE__ - cpu_type_t cputype; - size_t length; - - length = sizeof (cputype); - sysctlbyname ("hw.cputype", &cputype, &length, nullptr, 0); - switch (cputype) { - case CPU_TYPE_X86: - *running_on_cpu = CPU_KIND_X86; - break; - - case CPU_TYPE_X86_64: - *running_on_cpu = CPU_KIND_X86_64; - break; - - default: - *running_on_cpu = CPU_KIND_UNKNOWN; - break; - } - - return 1; -#else - return 0; -#endif + *built_for_cpu = CPU_KIND_UNKNOWN; } static int @@ -213,14 +102,9 @@ get_running_on_cpu_android ([[maybe_unused]] unsigned short *running_on_cpu) static void get_running_on_cpu (unsigned short *running_on_cpu) { - if (get_running_on_cpu_windows (running_on_cpu)) - return; - - if (get_running_on_cpu_apple (running_on_cpu)) - return; - - if (get_running_on_cpu_android (running_on_cpu)) + if (get_running_on_cpu_android (running_on_cpu)) { return; + } *running_on_cpu = CPU_KIND_UNKNOWN; } diff --git a/src/monodroid/jni/cpu-arch.hh b/src/monodroid/jni/cpu-arch.hh index 527a1e1e29e..29c210d47f4 100644 --- a/src/monodroid/jni/cpu-arch.hh +++ b/src/monodroid/jni/cpu-arch.hh @@ -10,8 +10,5 @@ #define CPU_KIND_X86 ((unsigned short)4) #define CPU_KIND_X86_64 ((unsigned short)5) -#if !defined(NET) -MONO_API -#endif // def NET void _monodroid_detect_cpu_and_architecture (unsigned short *built_for_cpu, unsigned short *running_on_cpu, unsigned char *is64bit); #endif // ndef NET diff --git a/src/monodroid/jni/debug-app-helper.cc b/src/monodroid/jni/debug-app-helper.cc index e79c62b238d..eb7066b6e62 100644 --- a/src/monodroid/jni/debug-app-helper.cc +++ b/src/monodroid/jni/debug-app-helper.cc @@ -1,14 +1,13 @@ #include +#include #include -#include #include #include #include #include -#ifdef ANDROID + #include -#endif #include "basic-android-system.hh" #include "basic-utilities.hh" @@ -38,23 +37,6 @@ bool maybe_load_library (const char *path); __android_log_vprint ((_level_), (_tag_), (_format_), (_args_)); \ va_end ((_args_)); -#ifndef ANDROID -#define ANDROID_LOG_INFO 1 -#define ANDROID_LOG_WARN 2 -#define ANDROID_LOG_ERROR 3 -#define ANDROID_LOG_FATAL 4 -#define ANDROID_LOG_DEBUG 5 - -static void -__android_log_vprint (int prio, const char* tag, const char* fmt, va_list ap) -{ - printf ("%d [%s] ", prio, tag); - vprintf (fmt, ap); - putchar ('\n'); - fflush (stdout); -} -#endif - static constexpr char TAG[] = "debug-app-helper"; unsigned int log_categories = LOG_DEFAULT | LOG_ASSEMBLY; @@ -95,7 +77,6 @@ Java_mono_android_DebugRuntime_init (JNIEnv *env, [[maybe_unused]] jclass klass, } } -#if defined (ANDROID) static void copy_file_to_internal_location (char *to_dir, char *from_dir, char *file) { @@ -130,21 +111,15 @@ copy_file_to_internal_location (char *to_dir, char *from_dir, char *file) delete[] from_file; delete[] to_file; } -#else /* !defined (ANDROID) */ -static void -copy_file_to_internal_location ([[maybe_unused]] char *to_dir, [[maybe_unused]] char *from_dir, [[maybe_unused]] char* file) -{ -} -#endif /* defined (ANDROID) */ static void copy_native_libraries_to_internal_location () { - for (size_t i = 0; i < BasicAndroidSystem::MAX_OVERRIDES; ++i) { - monodroid_dir_t *dir; - monodroid_dirent_t *e; + for (const char *od : BasicAndroidSystem::override_dirs) { + DIR *dir; + dirent *e; - char *dir_path = utils.path_combine (BasicAndroidSystem::override_dirs [i], "lib"); + char *dir_path = utils.path_combine (od, "lib"); log_warn (LOG_DEFAULT, "checking directory: `%s`", dir_path); if (dir_path == nullptr || !utils.directory_exists (dir_path)) { @@ -153,7 +128,7 @@ copy_native_libraries_to_internal_location () continue; } - if ((dir = utils.monodroid_opendir (dir_path)) == nullptr) { + if ((dir = ::opendir (dir_path)) == nullptr) { log_warn (LOG_DEFAULT, "could not open directory: `%s`", dir_path); delete[] dir_path; continue; @@ -162,18 +137,10 @@ copy_native_libraries_to_internal_location () while ((e = readdir (dir)) != nullptr) { log_warn (LOG_DEFAULT, "checking file: `%s`", e->d_name); if (utils.monodroid_dirent_hasextension (e, ".so")) { -#if WINDOWS - char *file_name = utils.utf16_to_utf8 (e->d_name); -#else /* def WINDOWS */ - char *file_name = e->d_name; -#endif /* ndef WINDOWS */ - copy_file_to_internal_location (androidSystem.get_primary_override_dir (), dir_path, file_name); -#if WINDOWS - free (file_name); -#endif /* def WINDOWS */ + copy_file_to_internal_location (androidSystem.get_primary_override_dir (), dir_path, e->d_name); } } - utils.monodroid_closedir (dir); + ::closedir (dir); delete[] dir_path; } } @@ -207,17 +174,17 @@ get_libmonosgen_path () copy_native_libraries_to_internal_location (); if (androidSystem.is_embedded_dso_mode_enabled ()) { - return SharedConstants::MONO_SGEN_SO; + return SharedConstants::MONO_SGEN_SO.data (); } - for (size_t i = 0; i < BasicAndroidSystem::MAX_OVERRIDES; ++i) { - if (runtime_exists (BasicAndroidSystem::override_dirs [i], libmonoso)) { + for (const char *od : BasicAndroidSystem::override_dirs) { + if (runtime_exists (od, libmonoso)) { return libmonoso; } } - for (size_t i = 0; i < BasicAndroidSystem::app_lib_directories_size; i++) { - if (runtime_exists (BasicAndroidSystem::app_lib_directories [i], libmonoso)) { + for (const char *app_lib_dir : BasicAndroidSystem::app_lib_directories) { + if (runtime_exists (app_lib_dir, libmonoso)) { return libmonoso; } } @@ -255,23 +222,18 @@ get_libmonosgen_path () return libmonoso; delete[] libmonoso; -#ifdef WINDOWS - if (runtime_exists (get_libmonoandroid_directory_path (), libmonoso)) - return libmonoso; -#endif - - if (runtime_exists (BasicAndroidSystem::SYSTEM_LIB_PATH, libmonoso)) + if (runtime_exists (BasicAndroidSystem::SYSTEM_LIB_PATH.data (), libmonoso)) return libmonoso; log_fatal (LOG_DEFAULT, "Cannot find '%s'. Looked in the following locations:", SharedConstants::MONO_SGEN_SO); - for (size_t i = 0; i < BasicAndroidSystem::MAX_OVERRIDES; ++i) { - if (BasicAndroidSystem::override_dirs [i] == nullptr) + for (const char *od : BasicAndroidSystem::override_dirs) { + if (od == nullptr) continue; - log_fatal (LOG_DEFAULT, " %s", BasicAndroidSystem::override_dirs [i]); + log_fatal (LOG_DEFAULT, " %s", od); } - for (size_t i = 0; i < BasicAndroidSystem::app_lib_directories_size; i++) { - log_fatal (LOG_DEFAULT, " %s", BasicAndroidSystem::app_lib_directories [i]); + for (const char *app_lib_dir : BasicAndroidSystem::app_lib_directories) { + log_fatal (LOG_DEFAULT, " %s", app_lib_dir); } log_fatal (LOG_DEFAULT, "Do you have a shared runtime build of your app with AndroidManifest.xml android:minSdkVersion < 10 while running on a 64-bit Android 5.0 target? This combination is not supported."); diff --git a/src/monodroid/jni/debug-constants.cc b/src/monodroid/jni/debug-constants.cc index 3631bad7266..82fa9f30008 100644 --- a/src/monodroid/jni/debug-constants.cc +++ b/src/monodroid/jni/debug-constants.cc @@ -2,24 +2,7 @@ using namespace xamarin::android; -// These are moved here so that the Windows build works and we don't need to -// #ifdef references to these out in this case. Debugging code generally works -// only on Unix atm -const char Debug::DEBUG_MONO_CONNECT_PROPERTY[] = "debug.mono.connect"; -const char Debug::DEBUG_MONO_DEBUG_PROPERTY[] = "debug.mono.debug"; -const char Debug::DEBUG_MONO_ENV_PROPERTY[] = "debug.mono.env"; -const char Debug::DEBUG_MONO_EXTRA_PROPERTY[] = "debug.mono.extra"; -const char Debug::DEBUG_MONO_GC_PROPERTY[] = "debug.mono.gc"; -const char Debug::DEBUG_MONO_GDB_PROPERTY[] = "debug.mono.gdb"; -const char Debug::DEBUG_MONO_LOG_PROPERTY[] = "debug.mono.log"; -const char Debug::DEBUG_MONO_MAX_GREFC[] = "debug.mono.max_grefc"; -const char Debug::DEBUG_MONO_PROFILE_PROPERTY[] = "debug.mono.profile"; -const char Debug::DEBUG_MONO_RUNTIME_ARGS_PROPERTY[] = "debug.mono.runtime_args"; -const char Debug::DEBUG_MONO_SOFT_BREAKPOINTS[] = "debug.mono.soft_breakpoints"; -const char Debug::DEBUG_MONO_TRACE_PROPERTY[] = "debug.mono.trace"; -const char Debug::DEBUG_MONO_WREF_PROPERTY[] = "debug.mono.wref"; - extern "C" const char *__get_debug_mono_log_property (void) { - return static_cast (Debug::DEBUG_MONO_LOG_PROPERTY); + return static_cast (Debug::DEBUG_MONO_LOG_PROPERTY.data ()); } diff --git a/src/monodroid/jni/debug.cc b/src/monodroid/jni/debug.cc index 3b911106a99..33f9c0aaa67 100644 --- a/src/monodroid/jni/debug.cc +++ b/src/monodroid/jni/debug.cc @@ -6,35 +6,27 @@ // Based on code from mt's libmonotouch/debug.m file. // +#include +#include #include #include #include +#include -#ifndef WINDOWS #include #include #include #include #include #include -#endif - #include #include #include #include -#include -#include #include -#ifdef ANDROID #include -#endif - -#if defined (APPLE_OS_X) -#include -#endif // def APPLE_OX_X #include "java-interop-util.h" @@ -131,7 +123,7 @@ Debug::load_profiler_from_handle (void *dso_handle, const char *desc, const char if (!dso_handle) return false; - std::unique_ptr symbol {utils.string_concat (INITIALIZER_NAME, "_", name)}; + std::unique_ptr symbol {utils.string_concat (INITIALIZER_NAME.data (), "_", name)}; bool result = load_profiler (dso_handle, desc, symbol.get ()); if (result) @@ -140,7 +132,7 @@ Debug::load_profiler_from_handle (void *dso_handle, const char *desc, const char return false; } -#if defined (DEBUG) && !defined (WINDOWS) +#if defined (DEBUG) void Debug::set_debugger_log_level (const char *level) { @@ -239,7 +231,7 @@ void Debug::start_debugging_and_profiling () { size_t total_time_index; - if (XA_UNLIKELY (FastTiming::enabled ())) { + if (FastTiming::enabled ()) [[unlikely]] { total_time_index = internal_timing->start_event (TimingEventKind::DebugStart); } @@ -260,7 +252,7 @@ Debug::start_debugging_and_profiling () } delete[] connect_args; - if (XA_UNLIKELY (FastTiming::enabled ())) { + if (FastTiming::enabled ()) [[unlikely]] { internal_timing->end_event (total_time_index); } } @@ -438,39 +430,40 @@ Debug::handle_server_connection (void) bool Debug::process_cmd (int fd, char *cmd) { - static constexpr char CONNECT_OUTPUT_CMD[] = "connect output"; - if (strcmp (cmd, CONNECT_OUTPUT_CMD) == 0) { + constexpr std::string_view CONNECT_OUTPUT_CMD { "connect output" }; + if (strcmp (cmd, CONNECT_OUTPUT_CMD.data ()) == 0) { dup2 (fd, 1); dup2 (fd, 2); return true; } - static constexpr char CONNECT_STDOUT_CMD[] = "connect stdout"; - if (strcmp (cmd, CONNECT_STDOUT_CMD) == 0) { + constexpr std::string_view CONNECT_STDOUT_CMD { "connect stdout" }; + if (strcmp (cmd, CONNECT_STDOUT_CMD.data ()) == 0) { dup2 (fd, 1); return true; } - static constexpr char CONNECT_STDERR_CMD[] = "connect stderr"; - if (strcmp (cmd, CONNECT_STDERR_CMD) == 0) { + constexpr std::string_view CONNECT_STDERR_CMD { "connect stderr" }; + if (strcmp (cmd, CONNECT_STDERR_CMD.data ()) == 0) { dup2 (fd, 2); return true; } - static constexpr char DISCARD_CMD[] = "discard"; - if (strcmp (cmd, DISCARD_CMD) == 0) { + constexpr std::string_view DISCARD_CMD { "discard" }; + if (strcmp (cmd, DISCARD_CMD.data ()) == 0) { return true; } - static constexpr char PING_CMD[] = "ping"; - if (strcmp (cmd, PING_CMD) == 0) { - if (!utils.send_uninterrupted (fd, const_cast (reinterpret_cast ("pong")), 5)) + constexpr std::string_view PING_CMD { "ping" }; + constexpr std::string_view PONG_REPLY { "pong" }; + if (strcmp (cmd, PING_CMD.data ()) == 0) { + if (!utils.send_uninterrupted (fd, const_cast (reinterpret_cast (PONG_REPLY.data ())), 5)) log_error (LOG_DEFAULT, "Got keepalive request from XS, but could not send response back (%s)\n", strerror (errno)); return false; } - static constexpr char EXIT_PROCESS_CMD[] = "exit process"; - if (strcmp (cmd, EXIT_PROCESS_CMD) == 0) { + constexpr std::string_view EXIT_PROCESS_CMD { "exit process" }; + if (strcmp (cmd, EXIT_PROCESS_CMD.data ()) == 0) { log_info (LOG_DEFAULT, "Debugger requested an exit, will exit immediately.\n"); fflush (stdout); fflush (stderr); @@ -478,16 +471,15 @@ Debug::process_cmd (int fd, char *cmd) } bool use_fd = false; - static constexpr char START_DEBUGGER_CMD[] = "start debugger: "; - static constexpr size_t START_DEBUGGER_CMD_LEN = sizeof(START_DEBUGGER_CMD) - 1; - static constexpr char VALUE_NO[] = "no"; - if (strncmp (cmd, START_DEBUGGER_CMD, START_DEBUGGER_CMD_LEN) == 0) { - const char *debugger = cmd + START_DEBUGGER_CMD_LEN; - - static constexpr char DEBUGGER_SDB[] = "sdb"; - if (strcmp (debugger, VALUE_NO) == 0) { + constexpr std::string_view START_DEBUGGER_CMD { "start debugger: " }; + constexpr std::string_view VALUE_NO { "no" }; + if (strncmp (cmd, START_DEBUGGER_CMD.data (), START_DEBUGGER_CMD.length ()) == 0) { + const char *debugger = cmd + START_DEBUGGER_CMD.length (); + + constexpr std::string_view DEBUGGER_SDB { "sdb" }; + if (strcmp (debugger, VALUE_NO.data ()) == 0) { /* disabled */ - } else if (strcmp (debugger, DEBUGGER_SDB) == 0) { + } else if (strcmp (debugger, DEBUGGER_SDB.data ()) == 0) { sdb_fd = fd; use_fd = true; } @@ -499,16 +491,15 @@ Debug::process_cmd (int fd, char *cmd) return use_fd; } - static constexpr char START_PROFILER_CMD[] = "start profiler: "; - static constexpr size_t START_PROFILER_CMD_LEN = sizeof(START_PROFILER_CMD) - 1; - if (strncmp (cmd, START_PROFILER_CMD, START_PROFILER_CMD_LEN) == 0) { - const char *prof = cmd + START_PROFILER_CMD_LEN; + constexpr std::string_view START_PROFILER_CMD { "start profiler: " }; + if (strncmp (cmd, START_PROFILER_CMD.data (), START_PROFILER_CMD.length ()) == 0) { + const char *prof = cmd + START_PROFILER_CMD.length (); + + constexpr std::string_view PROFILER_LOG { "log:" }; - static constexpr char PROFILER_LOG[] = "log:"; - static constexpr size_t PROFILER_LOG_LEN = sizeof(PROFILER_LOG) - 1; - if (strcmp (prof, VALUE_NO) == 0) { + if (strcmp (prof, VALUE_NO.data ()) == 0) { /* disabled */ - } else if (strncmp (prof, PROFILER_LOG, PROFILER_LOG_LEN) == 0) { + } else if (strncmp (prof, PROFILER_LOG.data (), PROFILER_LOG.length ()) == 0) { use_fd = true; profiler_fd = fd; profiler_description = utils.monodroid_strdup_printf ("%s,output=#%i", prof, profiler_fd); @@ -528,8 +519,6 @@ Debug::process_cmd (int fd, char *cmd) return false; } -#if !defined (WINDOWS) - void Debug::start_debugging (void) { @@ -547,7 +536,7 @@ Debug::start_debugging (void) embeddedAssemblies.set_register_debug_symbols (true); char *debug_arg = utils.monodroid_strdup_printf ("--debugger-agent=transport=socket-fd,address=%d,embedding=1", sdb_fd); - char *debug_options[] = { + std::array debug_options = { debug_arg, nullptr }; @@ -557,11 +546,11 @@ Debug::start_debugging (void) log_warn (LOG_DEBUGGER, "Trying to initialize the debugger with options: %s", debug_arg); if (enable_soft_breakpoints ()) { - constexpr char soft_breakpoints[] = "--soft-breakpoints"; - debug_options[1] = const_cast (soft_breakpoints); - mono_jit_parse_options (2, debug_options); + constexpr std::string_view soft_breakpoints { "--soft-breakpoints" }; + debug_options[1] = const_cast (soft_breakpoints.data ()); + mono_jit_parse_options (2, debug_options.data ()); } else { - mono_jit_parse_options (1, debug_options); + mono_jit_parse_options (1, debug_options.data ()); } mono_debug_init (MONO_DEBUG_FORMAT_MONO); @@ -585,10 +574,6 @@ Debug::start_profiling () monodroid_profiler_load (androidSystem.get_runtime_libdir (), profiler_description, nullptr); } -#endif // !def WINDOWS - -#ifdef ANDROID -#ifdef DEBUG static const char *soft_breakpoint_kernel_list[] = { "2.6.32.21-g1e30168", nullptr }; @@ -613,33 +598,21 @@ Debug::enable_soft_breakpoints (void) char *value; /* Soft breakpoints are enabled by default */ if (androidSystem.monodroid_get_system_property (Debug::DEBUG_MONO_SOFT_BREAKPOINTS, &value) <= 0) { - log_info (LOG_DEBUGGER, "soft breakpoints enabled by default (%s property not defined)", Debug::DEBUG_MONO_SOFT_BREAKPOINTS); + log_info (LOG_DEBUGGER, "soft breakpoints enabled by default (%s property not defined)", Debug::DEBUG_MONO_SOFT_BREAKPOINTS.data ()); return 1; } bool ret; if (strcmp ("0", value) == 0) { ret = false; - log_info (LOG_DEBUGGER, "soft breakpoints disabled (%s property set to %s)", Debug::DEBUG_MONO_SOFT_BREAKPOINTS, value); + log_info (LOG_DEBUGGER, "soft breakpoints disabled (%s property set to %s)", Debug::DEBUG_MONO_SOFT_BREAKPOINTS.data (), value); } else { ret = true; - log_info (LOG_DEBUGGER, "soft breakpoints enabled (%s property set to %s)", Debug::DEBUG_MONO_SOFT_BREAKPOINTS, value); + log_info (LOG_DEBUGGER, "soft breakpoints enabled (%s property set to %s)", Debug::DEBUG_MONO_SOFT_BREAKPOINTS.data (), value); } delete[] value; return ret; } -#endif /* DEBUG */ -#else /* !defined (ANDROID) */ -#if defined (DEBUG) && !defined (WINDOWS) -#ifndef enable_soft_breakpoints -[[maybe_unused]] bool -Debug::enable_soft_breakpoints (void) -{ - return false; -} -#endif /* DEBUG */ -#endif // enable_soft_breakpoints -#endif /* defined (ANDROID) */ // TODO: this is less than ideal. We can't use std::function or std::bind beause we // don't have the C++ stdlib on Android (well, we do but including it would make the diff --git a/src/monodroid/jni/debug.hh b/src/monodroid/jni/debug.hh index a5e596e8608..9eafaa05624 100644 --- a/src/monodroid/jni/debug.hh +++ b/src/monodroid/jni/debug.hh @@ -3,6 +3,8 @@ #define __MONODROID_DEBUG_H__ #include +#include + #include #include @@ -25,23 +27,23 @@ namespace xamarin::android }; private: - static constexpr char INITIALIZER_NAME[] = "mono_profiler_init"; + static inline constexpr std::string_view INITIALIZER_NAME { "mono_profiler_init" }; public: /* Android property containing connection information, set by XS */ - static const char DEBUG_MONO_CONNECT_PROPERTY[]; - static const char DEBUG_MONO_DEBUG_PROPERTY[]; - static const char DEBUG_MONO_ENV_PROPERTY[]; - static const char DEBUG_MONO_EXTRA_PROPERTY[]; - static const char DEBUG_MONO_GC_PROPERTY[]; - static const char DEBUG_MONO_GDB_PROPERTY[]; - static const char DEBUG_MONO_LOG_PROPERTY[]; - static const char DEBUG_MONO_MAX_GREFC[]; - static const char DEBUG_MONO_PROFILE_PROPERTY[]; - static const char DEBUG_MONO_RUNTIME_ARGS_PROPERTY[]; - static const char DEBUG_MONO_SOFT_BREAKPOINTS[]; - static const char DEBUG_MONO_TRACE_PROPERTY[]; - static const char DEBUG_MONO_WREF_PROPERTY[]; + static inline constexpr std::string_view DEBUG_MONO_CONNECT_PROPERTY { "debug.mono.connect" }; + static inline constexpr std::string_view DEBUG_MONO_DEBUG_PROPERTY { "debug.mono.debug" }; + static inline constexpr std::string_view DEBUG_MONO_ENV_PROPERTY { "debug.mono.env" }; + static inline constexpr std::string_view DEBUG_MONO_EXTRA_PROPERTY { "debug.mono.extra" }; + static inline constexpr std::string_view DEBUG_MONO_GC_PROPERTY { "debug.mono.gc" }; + static inline constexpr std::string_view DEBUG_MONO_GDB_PROPERTY { "debug.mono.gdb" }; + static inline constexpr std::string_view DEBUG_MONO_LOG_PROPERTY { "debug.mono.log" }; + static inline constexpr std::string_view DEBUG_MONO_MAX_GREFC { "debug.mono.max_grefc" }; + static inline constexpr std::string_view DEBUG_MONO_PROFILE_PROPERTY { "debug.mono.profile" }; + static inline constexpr std::string_view DEBUG_MONO_RUNTIME_ARGS_PROPERTY { "debug.mono.runtime_args" }; + static inline constexpr std::string_view DEBUG_MONO_SOFT_BREAKPOINTS { "debug.mono.soft_breakpoints" }; + static inline constexpr std::string_view DEBUG_MONO_TRACE_PROPERTY { "debug.mono.trace" }; + static inline constexpr std::string_view DEBUG_MONO_WREF_PROPERTY { "debug.mono.wref" }; public: explicit Debug () @@ -53,7 +55,7 @@ namespace xamarin::android bool load_profiler (void *handle, const char *desc, const char *symbol); bool load_profiler_from_handle (void *dso_handle, const char *desc, const char *name); -#if !defined (WINDOWS) && defined (DEBUG) +#if defined (DEBUG) public: bool enable_soft_breakpoints (); void start_debugging_and_profiling (); @@ -95,7 +97,7 @@ namespace xamarin::android timespec wait_ts; bool got_debugger_log_level = false; int debugger_log_level = 0; -#endif +#endif // def DEBUG }; } #else // __cplusplus diff --git a/src/monodroid/jni/embedded-assemblies-zip.cc b/src/monodroid/jni/embedded-assemblies-zip.cc index f7be28a631e..294c20c49e3 100644 --- a/src/monodroid/jni/embedded-assemblies-zip.cc +++ b/src/monodroid/jni/embedded-assemblies-zip.cc @@ -8,31 +8,17 @@ #include #include "embedded-assemblies.hh" -#include "cpp-util.hh" #include "globals.hh" #include "xamarin-app.hh" using namespace xamarin::android::internal; -// This type is needed when calling read(2) in a MinGW build, as it defines the `count` parameter as `unsigned int` -// instead of `size_t` which then causes the following warning if we pass a value of type `size_t`: -// -// warning: conversion from ‘size_t’ {aka ‘long long unsigned int’} to ‘unsigned int’ may change value [-Wconversion] -// -#if defined (WINDOWS) -using read_count_type = unsigned int; -#else using read_count_type = size_t; -#endif force_inline bool EmbeddedAssemblies::is_debug_file (dynamic_local_string const& name) noexcept { - return utils.ends_with (name, ".pdb") -#if !defined (NET) - || utils.ends_with (name, ".mdb") -#endif - ; + return utils.ends_with (name, ".pdb"); } force_inline bool @@ -65,7 +51,6 @@ EmbeddedAssemblies::zip_load_entry_common (size_t entry_index, std::vector c continue; } -#if !defined(NET) - if (utils.ends_with (entry_name, ".config")) { - char *assembly_name = strdup (basename (entry_name.get ())); - // Remove '.config' suffix - *strrchr (assembly_name, '.') = '\0'; - - md_mmap_info map_info = md_mmap_apk_file (state.apk_fd, state.data_offset, state.file_size, entry_name.get ()); - mono_register_config_for_assembly (assembly_name, (const char*)map_info.area); - - continue; - } -#endif // ndef NET - if (!utils.ends_with (entry_name, SharedConstants::DLL_EXTENSION)) continue; @@ -145,7 +116,7 @@ EmbeddedAssemblies::zip_load_individual_assembly_entries (std::vector c continue; #endif - if (XA_UNLIKELY (bundled_assembly_index >= application_config.number_of_assemblies_in_apk || bundled_assemblies_slow_path)) { + if (bundled_assembly_index >= application_config.number_of_assemblies_in_apk || bundled_assemblies_slow_path) [[unlikely]] { if (!bundled_assemblies_slow_path && bundled_assembly_index == application_config.number_of_assemblies_in_apk) { log_warn (LOG_ASSEMBLY, "Number of assemblies stored at build time (%u) was incorrect, switching to slow bundling path."); } @@ -370,7 +341,7 @@ EmbeddedAssemblies::zip_read_cd_info (int fd, uint32_t& cd_offset, uint32_t& cd_ return false; } - if (memcmp (signature.data (), ZIP_EOCD_MAGIC, signature.size ()) == 0) { + if (memcmp (signature.data (), ZIP_EOCD_MAGIC.data (), signature.size ()) == 0) { return zip_extract_cd_info (eocd, cd_offset, cd_size, cd_entries); } @@ -395,7 +366,7 @@ EmbeddedAssemblies::zip_read_cd_info (int fd, uint32_t& cd_offset, uint32_t& cd_ bool found = false; const uint8_t* data = buf.data (); for (ssize_t i = static_cast(alloc_size - (ZIP_EOCD_LEN + 2)); i >= 0; i--) { - if (memcmp (data + i, ZIP_EOCD_MAGIC, sizeof(ZIP_EOCD_MAGIC)) != 0) + if (memcmp (data + i, ZIP_EOCD_MAGIC.data (), sizeof(ZIP_EOCD_MAGIC)) != 0) continue; found = true; @@ -438,7 +409,7 @@ EmbeddedAssemblies::zip_adjust_data_offset (int fd, ZipEntryLoadState &state) return false; } - if (memcmp (signature.data (), ZIP_LOCAL_MAGIC, signature.size ()) != 0) { + if (memcmp (signature.data (), ZIP_LOCAL_MAGIC.data (), signature.size ()) != 0) { log_error (LOG_ASSEMBLY, "Invalid Local Header entry signature at offset %u", state.local_header_offset); return false; } @@ -575,7 +546,7 @@ EmbeddedAssemblies::zip_read_entry_info (std::vector const& buf, dynami return false; } - if (memcmp (signature.data (), ZIP_CENTRAL_MAGIC, signature.size ()) != 0) { + if (memcmp (signature.data (), ZIP_CENTRAL_MAGIC.data (), signature.size ()) != 0) { log_error (LOG_ASSEMBLY, "Invalid Central Directory entry signature"); return false; } diff --git a/src/monodroid/jni/embedded-assemblies.cc b/src/monodroid/jni/embedded-assemblies.cc index ac6fddfd36b..f53e696d96a 100644 --- a/src/monodroid/jni/embedded-assemblies.cc +++ b/src/monodroid/jni/embedded-assemblies.cc @@ -1,17 +1,15 @@ #include -#if !defined (__MINGW32__) || (defined (__MINGW32__) && __GNUC__ >= 10) +#include +#include #include -#endif // ndef MINGW32 || def MINGW32 && GNUC >= 10 #include #include #include -#include -#include #include -#include #include -#include +#include +#include #include #if defined (HAVE_LZ4) @@ -25,13 +23,9 @@ #include #include -#include "java-interop-util.h" - -#include "monodroid.h" #include "util.hh" #include "embedded-assemblies.hh" #include "globals.hh" -#include "monodroid-glue.hh" #include "mono-image-loader.hh" #include "xamarin-app.hh" #include "cpp-util.hh" @@ -84,14 +78,14 @@ EmbeddedAssemblies::set_assembly_data_and_size (uint8_t* source_assembly_data, u force_inline void EmbeddedAssemblies::get_assembly_data (uint8_t *data, uint32_t data_size, [[maybe_unused]] const char *name, uint8_t*& assembly_data, uint32_t& assembly_data_size) noexcept { -#if defined (ANDROID) && defined (HAVE_LZ4) && defined (RELEASE) +#if defined (HAVE_LZ4) && defined (RELEASE) auto header = reinterpret_cast(data); if (header->magic == COMPRESSED_DATA_MAGIC) { - if (XA_UNLIKELY (compressed_assemblies.descriptors == nullptr)) { + if (compressed_assemblies.descriptors == nullptr) [[unlikely]] { log_fatal (LOG_ASSEMBLY, "Compressed assembly found but no descriptor defined"); Helpers::abort_application (); } - if (XA_UNLIKELY (header->descriptor_index >= compressed_assemblies.count)) { + if (header->descriptor_index >= compressed_assemblies.count) [[unlikely]] { log_fatal (LOG_ASSEMBLY, "Invalid compressed assembly descriptor index %u", header->descriptor_index); Helpers::abort_application (); } @@ -106,7 +100,7 @@ EmbeddedAssemblies::get_assembly_data (uint8_t *data, uint32_t data_size, [[mayb return; } - if (XA_UNLIKELY (cad.data == nullptr)) { + if (cad.data == nullptr) [[unlikely]] { log_fatal (LOG_ASSEMBLY, "Invalid compressed assembly descriptor at %u: no data", header->descriptor_index); Helpers::abort_application (); } @@ -138,7 +132,7 @@ EmbeddedAssemblies::get_assembly_data (uint8_t *data, uint32_t data_size, [[mayb set_assembly_data_and_size (reinterpret_cast(cad.data), cad.uncompressed_file_size, assembly_data, assembly_data_size); } else -#endif +#endif // def HAVE_LZ4 && def RELEASE { set_assembly_data_and_size (data, data_size, assembly_data, assembly_data_size); } @@ -182,7 +176,7 @@ EmbeddedAssemblies::map_runtime_file (XamarinAndroidBundledAssembly& file) noexc } if constexpr (LogMapping) { - if (XA_UNLIKELY (utils.should_log (LOG_ASSEMBLY) && map_info.area != nullptr)) { + if (utils.should_log (LOG_ASSEMBLY) && map_info.area != nullptr) [[unlikely]] { const char *p = (const char*) file.data; std::array header; @@ -275,10 +269,6 @@ EmbeddedAssemblies::load_bundled_assembly ( return nullptr; } -#if !defined (NET) - // In dotnet the call is a no-op - mono_config_for_assembly (image); -#endif return a; } @@ -294,7 +284,7 @@ EmbeddedAssemblies::individual_assemblies_open_from_bundles (dynamic_local_strin dynamic_local_string abi_name; abi_name - .assign_c (BasicAndroidSystem::get_built_for_abi_name ()) + .assign (SharedConstants::android_lib_abi) .append (zip_path_separator) .append (name); @@ -322,7 +312,6 @@ EmbeddedAssemblies::individual_assemblies_open_from_bundles (dynamic_local_strin force_inline const AssemblyStoreHashEntry* EmbeddedAssemblies::find_assembly_store_entry ([[maybe_unused]] hash_t hash, [[maybe_unused]] const AssemblyStoreHashEntry *entries, [[maybe_unused]] size_t entry_count) noexcept { -#if !defined (__MINGW32__) || (defined (__MINGW32__) && __GNUC__ >= 10) hash_t entry_hash; const AssemblyStoreHashEntry *ret = nullptr; @@ -344,7 +333,6 @@ EmbeddedAssemblies::find_assembly_store_entry ([[maybe_unused]] hash_t hash, [[m return ret; } } -#endif // ndef __MINGW32__ || (def __MINGW32__ && __GNUC__ >= 10) return nullptr; } @@ -357,7 +345,7 @@ EmbeddedAssemblies::assembly_store_open_from_bundles (dynamic_local_stringdebug_data_offset != 0) { assembly_runtime_info.debug_info_data = rd.data_start + bba->debug_data_offset; } -#if !defined (NET) - if (bba->config_data_size != 0) { - assembly_runtime_info.config_data = rd.data_start + bba->config_data_offset; - - // Mono takes ownership of the pointers - mono_register_config_for_assembly ( - utils.string_concat (name.get (), ".dll"), - utils.strdup_new (reinterpret_cast(assembly_runtime_info.config_data)) - ); - } -#endif // NET log_debug ( LOG_ASSEMBLY, @@ -452,9 +429,6 @@ EmbeddedAssemblies::assembly_store_open_from_bundles (dynamic_local_string force_inline const Entry* @@ -591,7 +546,7 @@ EmbeddedAssemblies::binary_search (const Key *key, const Entry *base, size_t nme return nullptr; } -#if defined (RELEASE) && defined (ANDROID) +#if defined (RELEASE) force_inline const TypeMapModuleEntry* EmbeddedAssemblies::binary_search (uint32_t key, const TypeMapModuleEntry *arr, uint32_t n) noexcept { @@ -610,9 +565,9 @@ EmbeddedAssemblies::binary_search (uint32_t key, const TypeMapModuleEntry *arr, return arr[right].type_token_id == key ? &arr[right] : nullptr; } -#endif // def RELEASE && def ANDROID +#endif // def RELEASE -#if defined (DEBUG) || !defined (ANDROID) +#if defined (DEBUG) force_inline int EmbeddedAssemblies::compare_type_name (const char *type_name, const TypeMapEntry *entry) noexcept { @@ -640,7 +595,7 @@ EmbeddedAssemblies::typemap_java_to_managed ([[maybe_unused]] hash_t hash, const entry = binary_search (java_type_name.get (), type_map.java_to_managed, type_map.entry_count); } - if (XA_UNLIKELY (entry == nullptr)) { + if (entry == nullptr) [[unlikely]] { log_info (LOG_ASSEMBLY, "typemap: unable to find mapping to a managed type from Java type '%s'", java_type_name.get ()); return nullptr; } @@ -653,20 +608,20 @@ EmbeddedAssemblies::typemap_java_to_managed ([[maybe_unused]] hash_t hash, const log_debug (LOG_DEFAULT, "typemap: Java type '%s' corresponds to managed type '%s'", java_type_name.get (), managed_type_name); MonoType *type = mono_reflection_type_from_name (const_cast(managed_type_name), nullptr); - if (XA_UNLIKELY (type == nullptr)) { + if (type == nullptr) [[unlikely]] { log_info (LOG_ASSEMBLY, "typemap: managed type '%s' (mapped from Java type '%s') could not be loaded", managed_type_name, java_type_name.get ()); return nullptr; } MonoReflectionType *ret = mono_type_get_object (utils.get_current_domain (), type); - if (XA_UNLIKELY (ret == nullptr)) { + if (ret == nullptr) [[unlikely]] { log_warn (LOG_ASSEMBLY, "typemap: unable to instantiate managed type '%s'", managed_type_name); return nullptr; } return ret; } -#else +#else // def DEBUG force_inline MonoReflectionType* EmbeddedAssemblies::typemap_java_to_managed (hash_t hash, const MonoString *java_type_name) noexcept { @@ -732,14 +687,11 @@ EmbeddedAssemblies::typemap_java_to_managed (hash_t hash, const MonoString *java return nullptr; } -#if defined (NET) // MonoVM in dotnet runtime doesn't use the `domain` parameter passed to `mono_type_get_object` (since AppDomains // are gone in NET 6+), in fact, the function `mono_type_get_object` calls (`mono_type_get_object_checked`) itself // calls `mono_get_root_domain`. Thus, we can save on a one function call here by passing `nullptr` constexpr MonoDomain *domain = nullptr; -#else - MonoDomain *domain = utils.get_current_domain (); -#endif + MonoReflectionType *ret = mono_type_get_object (domain, mono_class_get_type (klass)); if (ret == nullptr) { log_warn (LOG_ASSEMBLY, "typemap: unable to instantiate managed type with token ID %u in assembly '%s', corresponding to Java type '%s'", java_entry->type_token_id, module->assembly_name, to_utf8 (java_type_name).get ()); @@ -748,18 +700,18 @@ EmbeddedAssemblies::typemap_java_to_managed (hash_t hash, const MonoString *java return ret; } -#endif +#endif // ndef DEBUG MonoReflectionType* EmbeddedAssemblies::typemap_java_to_managed (MonoString *java_type) noexcept { size_t total_time_index; - if (XA_UNLIKELY (FastTiming::enabled ())) { + if (FastTiming::enabled ()) [[unlikely]] { timing = new Timing (); total_time_index = internal_timing->start_event (TimingEventKind::JavaToManaged); } - if (XA_UNLIKELY (java_type == nullptr)) { + if (java_type == nullptr) [[unlikely]]{ log_warn (LOG_ASSEMBLY, "typemap: null 'java_type' passed to 'typemap_java_to_managed'"); return nullptr; } @@ -767,7 +719,7 @@ EmbeddedAssemblies::typemap_java_to_managed (MonoString *java_type) noexcept // We need to generate hash for all the bytes, and since MonoString is Unicode, we double the length to get the // number of bytes. int name_len = mono_string_length (java_type) << 1; - if (XA_UNLIKELY (name_len <= 0)) { + if (name_len <= 0) [[unlikely]] { log_warn (LOG_ASSEMBLY, "typemap: empty 'java_type' passed to 'typemap_java_to_managed'"); return nullptr; } @@ -776,14 +728,14 @@ EmbeddedAssemblies::typemap_java_to_managed (MonoString *java_type) noexcept hash_t hash = xxhash::hash (reinterpret_cast(type_chars), static_cast(name_len)); MonoReflectionType *ret = typemap_java_to_managed (hash, java_type); - if (XA_UNLIKELY (FastTiming::enabled ())) { + if (FastTiming::enabled ()) [[unlikely]] { internal_timing->end_event (total_time_index); } return ret; } -#if defined (DEBUG) || !defined (ANDROID) +#if defined (DEBUG) force_inline const TypeMapEntry* EmbeddedAssemblies::typemap_managed_to_java (const char *managed_type_name) noexcept { @@ -820,14 +772,14 @@ EmbeddedAssemblies::typemap_managed_to_java ([[maybe_unused]] MonoType *type, Mo .append (image_name, image_name_len); const TypeMapEntry *entry = typemap_managed_to_java (full_name.get ()); - if (XA_UNLIKELY (entry == nullptr)) { + if (entry == nullptr) [[unlikely]] { log_info (LOG_ASSEMBLY, "typemap: unable to find mapping to a Java type from managed type '%s'", full_name.get ()); return nullptr; } return entry->to; } -#else +#else // def DEBUG force_inline int EmbeddedAssemblies::compare_mvid (const uint8_t *mvid, const TypeMapModule *module) noexcept { @@ -868,19 +820,19 @@ EmbeddedAssemblies::typemap_managed_to_java ([[maybe_unused]] MonoType *type, Mo } } - if (XA_UNLIKELY (entry->java_map_index >= java_type_count)) { + if (entry->java_map_index >= java_type_count) [[unlikely]] { log_warn (LOG_ASSEMBLY, "typemap: type with token %d (0x%x) in module {%s} (%s) has invalid Java type index %u", token, token, MonoGuidString (mvid).get (), match->assembly_name, entry->java_map_index); return nullptr; } TypeMapJava const& java_entry = map_java[entry->java_map_index]; - if (XA_UNLIKELY (java_entry.java_name_index >= java_type_count)) { + if (java_entry.java_name_index >= java_type_count) [[unlikely]] { log_warn (LOG_ASSEMBLY, "typemap: type with token %d (0x%x) in module {%s} (%s) points to invalid Java type at index %u (invalid type name index %u)", token, token, MonoGuidString (mvid).get (), match->assembly_name, entry->java_map_index, java_entry.java_name_index); return nullptr; } const char *ret = java_type_names[java_entry.java_name_index]; - if (XA_UNLIKELY (ret == nullptr)) { + if (ret == nullptr) [[unlikely]] { log_warn (LOG_ASSEMBLY, "typemap: empty Java type name returned for entry at index %u", entry->java_map_index); } @@ -896,13 +848,13 @@ EmbeddedAssemblies::typemap_managed_to_java ([[maybe_unused]] MonoType *type, Mo return ret; } -#endif +#endif // ndef DEBUG const char* EmbeddedAssemblies::typemap_managed_to_java (MonoReflectionType *reflection_type, const uint8_t *mvid) noexcept { size_t total_time_index; - if (XA_UNLIKELY (FastTiming::enabled ())) { + if (FastTiming::enabled ()) [[unlikely]] { timing = new Timing (); total_time_index = internal_timing->start_event (TimingEventKind::ManagedToJava); } @@ -915,7 +867,7 @@ EmbeddedAssemblies::typemap_managed_to_java (MonoReflectionType *reflection_type const char *ret = typemap_managed_to_java (type, mono_class_from_mono_type (type), mvid); - if (XA_UNLIKELY (FastTiming::enabled ())) { + if (FastTiming::enabled ()) [[unlikely]] { internal_timing->end_event (total_time_index); } @@ -965,7 +917,7 @@ EmbeddedAssemblies::gather_bundled_assemblies_from_apk (const char* apk, monodro zip_load_entries (fd, apk, should_register); } -#if defined (DEBUG) || !defined (ANDROID) +#if defined (DEBUG) ssize_t EmbeddedAssemblies::do_read (int fd, void *buf, size_t count) { ssize_t ret; @@ -973,11 +925,7 @@ ssize_t EmbeddedAssemblies::do_read (int fd, void *buf, size_t count) ret = ::read ( fd, buf, -#if defined (WINDOWS) - static_cast(count) -#else count -#endif ); } while (ret < 0 && errno == EINTR); @@ -989,14 +937,7 @@ bool EmbeddedAssemblies::typemap_read_header ([[maybe_unused]] int dir_fd, const char *file_type, const char *dir_path, const char *file_path, uint32_t expected_magic, H &header, size_t &file_size, int &fd) { struct stat sbuf; - int res; - -#if __ANDROID_API__ < 21 - std::unique_ptr full_file_path {utils.path_combine (dir_path, file_path)}; - res = stat (full_file_path.get (), &sbuf); -#else - res = fstatat (dir_fd, file_path, &sbuf, 0); -#endif + int res = fstatat (dir_fd, file_path, &sbuf, 0); if (res < 0) { log_error (LOG_ASSEMBLY, "typemap: failed to stat %s file '%s/%s': %s", file_type, dir_path, file_path, strerror (errno)); return false; @@ -1008,11 +949,7 @@ EmbeddedAssemblies::typemap_read_header ([[maybe_unused]] int dir_fd, const char return false; } -#if __ANDROID_API__ < 21 - fd = open (full_file_path.get (), O_RDONLY); -#else fd = openat (dir_fd, file_path, O_RDONLY); -#endif if (fd < 0) { log_error (LOG_ASSEMBLY, "typemap: failed to open %s file %s/%s for reading: %s", file_type, dir_path, file_path, strerror (errno)); return false; @@ -1207,18 +1144,13 @@ EmbeddedAssemblies::try_load_typemaps_from_directory (const char *path) } std::unique_ptr dir_path {utils.path_combine (path, "typemaps")}; - monodroid_dir_t *dir; - if ((dir = utils.monodroid_opendir (dir_path.get ())) == nullptr) { + DIR *dir; + if ((dir = ::opendir (dir_path.get ())) == nullptr) { log_warn (LOG_ASSEMBLY, "typemap: could not open directory: `%s`", dir_path.get ()); return; } - int dir_fd; -#if __ANDROID_API__ < 21 - dir_fd = -1; -#else - dir_fd = dirfd (dir); -#endif + int dir_fd = dirfd (dir); constexpr char index_name[] = "typemap.index"; @@ -1237,9 +1169,9 @@ EmbeddedAssemblies::try_load_typemaps_from_directory (const char *path) } } - utils.monodroid_closedir (dir); + ::closedir (dir); } -#endif +#endif // def DEBUG size_t EmbeddedAssemblies::register_from (const char *apk_file, monodroid_should_register should_register) diff --git a/src/monodroid/jni/embedded-assemblies.hh b/src/monodroid/jni/embedded-assemblies.hh index 4b4c3324dae..fc0a0fc2472 100644 --- a/src/monodroid/jni/embedded-assemblies.hh +++ b/src/monodroid/jni/embedded-assemblies.hh @@ -3,50 +3,40 @@ #define INC_MONODROID_EMBEDDED_ASSEMBLIES_H #include - #include #include #include -#include +#include #include + #include #include #include - -#if defined (NET) #include -#endif #include "strings.hh" #include "xamarin-app.hh" #include "cpp-util.hh" -#include "mono-image-loader.hh" +#include "cppcompat.hh" #include "shared-constants.hh" #include "xxhash.hh" -#undef HAVE_CONCEPTS - -// Xcode has supports for concepts only since 12.5 -#if __has_include () -#define HAVE_CONCEPTS #include -#endif // __has_include struct TypeMapHeader; namespace xamarin::android::internal { -#if defined (DEBUG) || !defined (ANDROID) +#if defined (DEBUG) struct TypeMappingInfo; #endif -#if defined (RELEASE) && defined (ANDROID) +#if defined (RELEASE) #define STATIC_IN_ANDROID_RELEASE static #else #define STATIC_IN_ANDROID_RELEASE -#endif // def RELEASE && def ANDROID +#endif // def RELEASE -#if defined (HAVE_CONCEPTS) template concept ByteArrayContainer = requires (T a) { a.size (); @@ -56,16 +46,8 @@ namespace xamarin::android::internal { template concept LoaderData = requires (T a) { - requires std::same_as -#if defined (NET) - || std::same_as -#endif - ; + requires std::same_as || std::same_as; }; -#else -#define ByteArrayContainer class -#define LoaderData typename -#endif class EmbeddedAssemblies final { @@ -88,44 +70,41 @@ namespace xamarin::android::internal { }; private: - static constexpr char ZIP_CENTRAL_MAGIC[] = "PK\1\2"; - static constexpr char ZIP_LOCAL_MAGIC[] = "PK\3\4"; - static constexpr char ZIP_EOCD_MAGIC[] = "PK\5\6"; + static constexpr std::string_view ZIP_CENTRAL_MAGIC { "PK\1\2" }; + static constexpr std::string_view ZIP_LOCAL_MAGIC { "PK\3\4" }; + static constexpr std::string_view ZIP_EOCD_MAGIC { "PK\5\6" }; static constexpr off_t ZIP_EOCD_LEN = 22; static constexpr off_t ZIP_CENTRAL_LEN = 46; static constexpr off_t ZIP_LOCAL_LEN = 30; - static constexpr char assemblies_prefix[] = "assemblies/"; - static constexpr char zip_path_separator[] = "/"; + static constexpr std::string_view assemblies_prefix { "assemblies/" }; + static constexpr std::string_view zip_path_separator { "/" }; + static constexpr std::string_view dot { "." }; + static constexpr std::string_view assembly_store_prefix { "assemblies" }; + static constexpr std::string_view assembly_store_extension { ".blob" }; - static constexpr char assembly_store_prefix[] = "assemblies"; - static constexpr char assembly_store_extension[] = ".blob"; - static constexpr auto assembly_store_common_file_name = concat_const ("/", assembly_store_prefix, assembly_store_extension); - static constexpr auto assembly_store_arch_file_name = concat_const ("/", assembly_store_prefix, ".", SharedConstants::android_abi, assembly_store_extension); + static constexpr size_t assembly_store_common_file_name_size = calc_size (zip_path_separator, assembly_store_prefix, assembly_store_extension); + static constexpr auto assembly_store_common_file_name = concat_string_views (zip_path_separator, assembly_store_prefix, assembly_store_extension); - -#if defined (DEBUG) || !defined (ANDROID) - static constexpr char override_typemap_entry_name[] = ".__override__"; -#endif + static constexpr size_t assembly_store_arch_file_name_size = calc_size (zip_path_separator, assembly_store_prefix, dot, SharedConstants::android_abi, assembly_store_extension); + static constexpr auto assembly_store_arch_file_name = concat_string_views (zip_path_separator, assembly_store_prefix, dot, SharedConstants::android_abi, assembly_store_extension); public: /* filename is e.g. System.dll, System.dll.mdb, System.pdb */ using monodroid_should_register = bool (*)(const char *filename); public: -#if defined (RELEASE) && defined (ANDROID) +#if defined (RELEASE) EmbeddedAssemblies () noexcept {} -#endif // def RELEASE && def ANDROID +#endif // def RELEASE -#if defined (DEBUG) || !defined (ANDROID) +#if defined (DEBUG) void try_load_typemaps_from_directory (const char *path); #endif STATIC_IN_ANDROID_RELEASE const char* typemap_managed_to_java (MonoReflectionType *type, const uint8_t *mvid) noexcept; void install_preload_hooks_for_appdomains (); -#if defined (NET) void install_preload_hooks_for_alc (); -#endif // def NET STATIC_IN_ANDROID_RELEASE MonoReflectionType* typemap_java_to_managed (MonoString *java_type) noexcept; /* returns current number of *all* assemblies found from all invocations */ @@ -148,7 +127,6 @@ namespace xamarin::android::internal { void set_assemblies_prefix (const char *prefix); -#if defined (NET) void get_runtime_config_blob (const char *& area, uint32_t& size) const { area = static_cast(runtime_config_blob_mmap.area); @@ -161,7 +139,6 @@ namespace xamarin::android::internal { { return application_config.have_runtime_config_blob && runtime_config_blob_mmap.area != nullptr; } -#endif bool keep_scanning () const noexcept { @@ -205,7 +182,7 @@ namespace xamarin::android::internal { TLoaderData loader_data, bool ref_only) noexcept; -#if defined (DEBUG) || !defined (ANDROID) +#if defined (DEBUG) template bool typemap_read_header (int dir_fd, const char *file_type, const char *dir_path, const char *file_path, uint32_t expected_magic, H &header, size_t &file_size, int &fd); std::unique_ptr typemap_load_index (int dir_fd, const char *dir_path, const char *index_path); @@ -214,15 +191,12 @@ namespace xamarin::android::internal { 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; -#endif // DEBUG || !ANDROID +#endif // DEBUG static md_mmap_info md_mmap_apk_file (int fd, uint32_t offset, size_t size, const char* filename); static MonoAssembly* open_from_bundles_full (MonoAssemblyName *aname, char **assemblies_path, void *user_data); -#if defined (NET) static MonoAssembly* open_from_bundles (MonoAssemblyLoadContextGCHandle alc_gchandle, MonoAssemblyName *aname, char **assemblies_path, void *user_data, MonoError *error); -#else // def NET - static MonoAssembly* open_from_bundles_refonly (MonoAssemblyName *aname, char **assemblies_path, void *user_data); -#endif // ndef NET + 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; @@ -241,17 +215,6 @@ namespace xamarin::android::internal { template bool zip_ensure_valid_params (T const& buf, size_t index, size_t to_read) const noexcept; - // template - // bool zip_read_field (std::array const& buf, size_t index, uint16_t& u) - // { - // return zip_read_field_unchecked (buf, u, index); - // } - - // bool zip_read_field (std::vector const& buf, size_t index, uint16_t& u) - // { - // return zip_read_field_unchecked (buf, u, index); - // } - template bool zip_read_field (T const& src, size_t source_index, uint16_t& dst) const noexcept; @@ -268,21 +231,20 @@ namespace xamarin::android::internal { const char* get_assemblies_prefix () const { - return assemblies_prefix_override != nullptr ? assemblies_prefix_override : assemblies_prefix; + return assemblies_prefix_override != nullptr ? assemblies_prefix_override : assemblies_prefix.data (); } uint32_t get_assemblies_prefix_length () const noexcept { - return assemblies_prefix_override != nullptr ? static_cast(strlen (assemblies_prefix_override)) : sizeof(assemblies_prefix) - 1; + return assemblies_prefix_override != nullptr ? static_cast(strlen (assemblies_prefix_override)) : assemblies_prefix.length (); } bool all_required_zip_entries_found () const noexcept { return - number_of_mapped_assembly_stores == application_config.number_of_assembly_store_files -#if defined (NET) - && ((application_config.have_runtime_config_blob && runtime_config_blob_found) || !application_config.have_runtime_config_blob) -#endif // NET + number_of_mapped_assembly_stores == application_config.number_of_assembly_store_files && + ((application_config.have_runtime_config_blob && runtime_config_blob_found) || + !application_config.have_runtime_config_blob) ; } @@ -296,7 +258,7 @@ namespace xamarin::android::internal { template static const Entry* binary_search (const Key *key, const Entry *base, size_t nmemb, size_t extra_size = 0) noexcept; -#if defined (DEBUG) || !defined (ANDROID) +#if defined (DEBUG) static int compare_type_name (const char *type_name, const TypeMapEntry *entry) noexcept; #else static int compare_mvid (const uint8_t *mvid, const TypeMapModule *module) noexcept; @@ -318,17 +280,16 @@ namespace xamarin::android::internal { size_t bundled_assembly_index = 0; size_t number_of_found_assemblies = 0; -#if defined (DEBUG) || !defined (ANDROID) +#if defined (DEBUG) TypeMappingInfo *java_to_managed_maps; TypeMappingInfo *managed_to_java_maps; TypeMap *type_maps; size_t type_map_count; -#endif // DEBUG || !ANDROID +#endif // DEBUG const char *assemblies_prefix_override = nullptr; -#if defined (NET) + md_mmap_info runtime_config_blob_mmap{}; bool runtime_config_blob_found = false; -#endif // def NET uint32_t number_of_mapped_assembly_stores = 0; bool need_to_scan_more_apks = true; @@ -338,8 +299,4 @@ namespace xamarin::android::internal { }; } -#if !defined (NET) -MONO_API int monodroid_embedded_assemblies_set_assemblies_prefix (const char *prefix); -#endif // ndef NET - #endif /* INC_MONODROID_EMBEDDED_ASSEMBLIES_H */ diff --git a/src/monodroid/jni/globals.cc b/src/monodroid/jni/globals.cc index 697ef2d037c..eb1a2c87fe4 100644 --- a/src/monodroid/jni/globals.cc +++ b/src/monodroid/jni/globals.cc @@ -9,7 +9,5 @@ OSBridge osBridge; EmbeddedAssemblies embeddedAssemblies; MonodroidRuntime monodroidRuntime; Timing *timing = nullptr; -#ifndef ANDROID -DesignerAssemblies designerAssemblies; -#endif + Debug debug; diff --git a/src/monodroid/jni/globals.hh b/src/monodroid/jni/globals.hh index e163ffc2e00..67d482acea1 100644 --- a/src/monodroid/jni/globals.hh +++ b/src/monodroid/jni/globals.hh @@ -7,9 +7,7 @@ #include "debug.hh" #include "embedded-assemblies.hh" -#include "designer-assemblies.hh" #include "monodroid-glue-internal.hh" -#include "cppcompat.hh" extern xamarin::android::Debug debug; extern xamarin::android::Util utils; @@ -19,8 +17,4 @@ extern xamarin::android::internal::EmbeddedAssemblies embeddedAssemblies; extern xamarin::android::internal::MonodroidRuntime monodroidRuntime; extern xamarin::android::Timing *timing; -#ifndef ANDROID -extern xamarin::android::internal::DesignerAssemblies designerAssemblies; -#endif - #endif // !__GLOBALS_H diff --git a/src/monodroid/jni/helpers.hh b/src/monodroid/jni/helpers.hh index 2725b4d428c..fa89be2f66c 100644 --- a/src/monodroid/jni/helpers.hh +++ b/src/monodroid/jni/helpers.hh @@ -20,7 +20,7 @@ namespace xamarin::android { Ret ret; - if (XA_UNLIKELY (__builtin_add_overflow (a, b, &ret))) { + if (__builtin_add_overflow (a, b, &ret)) [[unlikely]] { log_fatal (LOG_DEFAULT, "Integer overflow on addition at %s:%u", file, line); abort_application (); } @@ -44,7 +44,7 @@ namespace xamarin::android { Ret ret; - if (XA_UNLIKELY (__builtin_mul_overflow (a, b, &ret))) { + if (__builtin_mul_overflow (a, b, &ret)) [[unlikely]] { log_fatal (LOG_DEFAULT, "Integer overflow on multiplication at %s:%u", file, line); abort_application (); } diff --git a/src/monodroid/jni/logger.cc b/src/monodroid/jni/logger.cc index 57f1ea79957..581d633df99 100644 --- a/src/monodroid/jni/logger.cc +++ b/src/monodroid/jni/logger.cc @@ -1,13 +1,12 @@ -#include -#include +#include +#include +#include +#include +#include #include -#include #include -#include -#ifdef ANDROID #include -#endif #include "logger.hh" @@ -27,7 +26,7 @@ using namespace xamarin::android; using namespace xamarin::android::internal; // Must match the same ordering as LogCategories -static const char* log_names[] = { +static constexpr std::array log_names = { "*none*", "monodroid", "monodroid-assembly", @@ -49,24 +48,7 @@ static const char* log_names[] = { #endif // ffs(value) returns index of lowest bit set in `value` -#define CATEGORY_NAME(value) (value == 0 ? log_names [0] : log_names [ffs (value)]) - -#ifndef ANDROID -static void -__android_log_vprint (int prio, const char* tag, const char* fmt, va_list ap) -{ - printf ("%d [%s] ", prio, tag); - vprintf (fmt, ap); - putchar ('\n'); - fflush (stdout); -} - -static void -__android_log_write (int prio, const char* tag, const char* message) -{ - printf ("%d [%s] %s\n", prio, tag, message); -} -#endif +#define CATEGORY_NAME(value) (value == 0 ? log_names [0] : log_names [static_cast(ffs (value))]) unsigned int log_categories = LOG_NONE; unsigned int log_timing_categories; @@ -97,8 +79,7 @@ open_file (LogCategories category, const char *path, const char *override_dir, c if (f) { utils.set_world_accessable (path); } else { - log_warn (category, "Could not open path '%s' for logging: %s", - path, strerror (errno)); + log_warn (category, "Could not open path '%s' for logging: %s", path, strerror (errno)); } free (p); @@ -128,15 +109,14 @@ init_reference_logging (const char *override_dir) } } -template force_inline static bool -set_category (const char (&name)[NameSize], string_segment& arg, unsigned int entry, bool arg_starts_with_name = false) +set_category (std::string_view const& name, string_segment& arg, unsigned int entry, bool arg_starts_with_name = false) { if ((log_categories & entry) == entry) { return false; } - if (arg_starts_with_name ? arg.starts_with (name, NameSize - 1) : arg.equal (name, NameSize - 1)) { + if (arg_starts_with_name ? arg.starts_with (name) : arg.equal (name)) { log_categories |= entry; return true; } @@ -149,10 +129,6 @@ init_logging_categories (char*& mono_log_mask, char*& mono_log_level) { mono_log_mask = nullptr; mono_log_level = nullptr; - -#if !ANDROID - log_categories = LOG_DEFAULT; -#endif log_timing_categories = LOG_TIMING_DEFAULT; dynamic_local_string value; @@ -161,10 +137,9 @@ init_logging_categories (char*& mono_log_mask, char*& mono_log_level) string_segment param; while (value.next_token (',', param)) { - constexpr char CAT_ALL[] = "all"; - constexpr size_t CAT_ALL_SIZE = sizeof(CAT_ALL) - 1; + constexpr std::string_view CAT_ALL { "all" }; - if (param.equal (CAT_ALL, CAT_ALL_SIZE)) { + if (param.equal (CAT_ALL)) { log_categories = 0xFFFFFFFF; break; } @@ -205,10 +180,9 @@ init_logging_categories (char*& mono_log_mask, char*& mono_log_level) continue; } - constexpr char CAT_GREF_EQUALS[] = "gref="; - constexpr size_t CAT_GREF_EQUALS_LEN = sizeof(CAT_GREF_EQUALS) - 1; + constexpr std::string_view CAT_GREF_EQUALS { "gref=" }; if (set_category (CAT_GREF_EQUALS, param, LOG_GREF, true /* arg_starts_with_name */)) { - gref_file = utils.strdup_new (param, CAT_GREF_EQUALS_LEN); + gref_file = utils.strdup_new (param, CAT_GREF_EQUALS.length ()); continue; } @@ -222,10 +196,9 @@ init_logging_categories (char*& mono_log_mask, char*& mono_log_level) continue; } - constexpr char CAT_LREF_EQUALS[] = "lref="; - constexpr size_t CAT_LREF_EQUALS_LEN = sizeof(CAT_LREF_EQUALS) - 1; + constexpr std::string_view CAT_LREF_EQUALS { "lref=" }; if (set_category (CAT_LREF_EQUALS, param, LOG_LREF, true /* arg_starts_with_name */)) { - lref_file = utils.strdup_new (param, CAT_LREF_EQUALS_LEN); + lref_file = utils.strdup_new (param, CAT_LREF_EQUALS.length ()); continue; } @@ -251,26 +224,23 @@ init_logging_categories (char*& mono_log_mask, char*& mono_log_level) continue; } - constexpr char MONO_LOG_MASK_ARG[] = "mono_log_mask="; - constexpr size_t MONO_LOG_MASK_ARG_LEN = sizeof(MONO_LOG_MASK_ARG) - 1; + constexpr std::string_view MONO_LOG_MASK_ARG { "mono_log_mask=" }; if (param.starts_with (MONO_LOG_MASK_ARG)) { - mono_log_mask = utils.strdup_new (param, MONO_LOG_MASK_ARG_LEN); + mono_log_mask = utils.strdup_new (param, MONO_LOG_MASK_ARG.length ()); continue; } - constexpr char MONO_LOG_LEVEL_ARG[] = "mono_log_level="; - constexpr size_t MONO_LOG_LEVEL_ARG_LEN = sizeof(MONO_LOG_LEVEL_ARG) - 1; + constexpr std::string_view MONO_LOG_LEVEL_ARG { "mono_log_level=" }; if (param.starts_with (MONO_LOG_LEVEL_ARG)) { - mono_log_level = utils.strdup_new (param, MONO_LOG_LEVEL_ARG_LEN); + mono_log_level = utils.strdup_new (param, MONO_LOG_LEVEL_ARG.length ()); continue; } -#if !defined (WINDOWS) && defined (DEBUG) - constexpr char DEBUGGER_LOG_LEVEL[] = "debugger-log-level="; - constexpr size_t DEBUGGER_LOG_LEVEL_LEN = sizeof (DEBUGGER_LOG_LEVEL) - 1; +#if defined (DEBUG) + constexpr std::string_view DEBUGGER_LOG_LEVEL { "debugger-log-level=" }; if (param.starts_with (DEBUGGER_LOG_LEVEL)) { dynamic_local_string level; - level.assign (param.start () + DEBUGGER_LOG_LEVEL_LEN, param.length () - DEBUGGER_LOG_LEVEL_LEN); + level.assign (param.start () + DEBUGGER_LOG_LEVEL.length (), param.length () - DEBUGGER_LOG_LEVEL.length ()); debug.set_debugger_log_level (level.get ()); } #endif diff --git a/src/monodroid/jni/logger.hh b/src/monodroid/jni/logger.hh index 2f65333751f..81951615025 100644 --- a/src/monodroid/jni/logger.hh +++ b/src/monodroid/jni/logger.hh @@ -3,20 +3,6 @@ #include "java-interop-logger.h" -#ifndef ANDROID -typedef enum android_LogPriority { - ANDROID_LOG_UNKNOWN = 0, - ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */ - ANDROID_LOG_VERBOSE, - ANDROID_LOG_DEBUG, - ANDROID_LOG_INFO, - ANDROID_LOG_WARN, - ANDROID_LOG_ERROR, - ANDROID_LOG_FATAL, - ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */ -} android_LogPriority; -#endif - void init_logging_categories (char*& mono_log_mask, char*& mono_log_level); void init_reference_logging (const char *override_dir); diff --git a/src/monodroid/jni/mono-image-loader.hh b/src/monodroid/jni/mono-image-loader.hh index 87bcbc2ed3a..419cdd41b89 100644 --- a/src/monodroid/jni/mono-image-loader.hh +++ b/src/monodroid/jni/mono-image-loader.hh @@ -6,9 +6,7 @@ #include #include -#if defined (NET) #include -#endif #include #include "platform-compat.hh" @@ -17,7 +15,7 @@ #include "search.hh" #include "strings.hh" -#if defined (RELEASE) && defined (ANDROID) && defined (NET) +#if defined (RELEASE) #define USE_CACHE 1 #endif @@ -52,7 +50,6 @@ namespace xamarin::android::internal { } #endif // def USE_CACHE -#if defined (NET) force_inline static MonoImage* load (dynamic_local_string const& name, MonoAssemblyLoadContextGCHandle alc_gchandle, hash_t name_hash, uint8_t *assembly_data, uint32_t assembly_data_size) noexcept { MonoImageOpenStatus status; @@ -72,7 +69,6 @@ namespace xamarin::android::internal { { return load (name, alc_gchandle, xxhash::hash (name.get (), name.length ()), assembly_data, assembly_data_size); } -#endif // def NET force_inline static MonoImage* load (dynamic_local_string const& name, bool ref_only, hash_t name_hash, uint8_t *assembly_data, uint32_t assembly_data_size) noexcept { diff --git a/src/monodroid/jni/monodroid-glue-internal.hh b/src/monodroid/jni/monodroid-glue-internal.hh index 84ac5f5188a..abd3401671c 100644 --- a/src/monodroid/jni/monodroid-glue-internal.hh +++ b/src/monodroid/jni/monodroid-glue-internal.hh @@ -3,6 +3,8 @@ #define __MONODROID_GLUE_INTERNAL_H #include +#include + #include #include "android-system.hh" #include "osbridge.hh" @@ -13,7 +15,6 @@ #include #include -#if defined (NET) // NDEBUG causes robin_map.h not to include which, in turn, prevents indirect inclusion of . // conflicts with our std::mutex definition in cppcompat.hh #if !defined (NDEBUG) @@ -41,13 +42,10 @@ //#include #include #include -#endif -#if defined (NET) // See https://github.com/dotnet/runtime/pull/67024 // See https://github.com/xamarin/xamarin-android/issues/6935 extern mono_bool mono_opt_aot_lazy_assembly_load; -#endif // def NET namespace xamarin::android::internal { @@ -68,7 +66,6 @@ namespace xamarin::android::internal class MonodroidRuntime { -#if defined (NET) using pinvoke_api_map = tsl::robin_map< std::string, void*, @@ -90,11 +87,8 @@ namespace xamarin::android::internal using load_assemblies_context_type = MonoAssemblyLoadContextGCHandle; static constexpr pinvoke_library_map::size_type LIBRARY_MAP_INITIAL_BUCKET_COUNT = 1; -#else // def NET - using load_assemblies_context_type = MonoDomain*; -#endif // ndef NET -#if defined (DEBUG) && !defined (WINDOWS) +#if defined (DEBUG) struct RuntimeOptions { bool debug = false; int loglevel = 0; @@ -135,40 +129,23 @@ namespace xamarin::android::internal bool marshalMethodsEnabled; }; -#if defined (NET) using jnienv_initialize_fn = void (*) (JnienvInitializeArgs*); using jnienv_register_jni_natives_fn = void (*)(const jchar *typeName_ptr, int32_t typeName_len, jclass jniClass, const jchar *methods_ptr, int32_t methods_len); -#endif private: - static constexpr char base_apk_name[] = "/base.apk"; + static constexpr std::string_view base_apk_name { "/base.apk" }; static constexpr size_t SMALL_STRING_PARSE_BUFFER_LEN = 50; - static constexpr bool is_running_on_desktop = -#if ANDROID - false; -#else - true; -#endif + static constexpr bool is_running_on_desktop = false; - static constexpr char mono_component_debugger_name[] = "libmono-component-debugger.so"; + static constexpr std::string_view mono_component_debugger_name { "libmono-component-debugger.so" }; static constexpr hash_t mono_component_debugger_hash = xxhash::hash (mono_component_debugger_name); - static constexpr char mono_component_hot_reload_name[] = "libmono-component-hot_reload.so"; + static constexpr std::string_view mono_component_hot_reload_name { "libmono-component-hot_reload.so" }; static constexpr hash_t mono_component_hot_reload_hash = xxhash::hash (mono_component_hot_reload_name); - static constexpr char mono_component_diagnostics_tracing_name[] = "libmono-component-diagnostics_tracing.so"; + static constexpr std::string_view mono_component_diagnostics_tracing_name { "libmono-component-diagnostics_tracing.so" }; static constexpr hash_t mono_component_diagnostics_tracing_hash = xxhash::hash (mono_component_diagnostics_tracing_name); -#if !defined (NET) -#define MAKE_API_DSO_NAME(_ext_) "libxa-internal-api." # _ext_ -#if defined (WINDOWS) - static constexpr char API_DSO_NAME[] = MAKE_API_DSO_NAME (dll); -#elif defined (APPLE_OS_X) - static constexpr char API_DSO_NAME[] = MAKE_API_DSO_NAME (dylib); -#else // !defined(WINDOWS) && !defined(APPLE_OS_X) - static constexpr char API_DSO_NAME[] = MAKE_API_DSO_NAME (so); -#endif // defined(WINDOWS) -#endif // ndef NET public: static constexpr int XA_LOG_COUNTERS = MONO_COUNTER_JIT | MONO_COUNTER_METADATA | MONO_COUNTER_GC | MONO_COUNTER_GENERICS | MONO_COUNTER_INTERP; @@ -178,13 +155,7 @@ namespace xamarin::android::internal jstring runtimeNativeLibDir, jobjectArray appDirs, jint localDateTimeOffset, jobject loader, jobjectArray assembliesJava, jint apiLevel, jboolean isEmulator, jboolean haveSplitApks); -#if !defined (ANDROID) - jint Java_mono_android_Runtime_createNewContextWithData (JNIEnv *env, jclass klass, jobjectArray runtimeApksJava, jobjectArray assembliesJava, - jobjectArray assembliesBytes, jobjectArray assembliesPaths, jobject loader, jboolean force_preload_assemblies); - void Java_mono_android_Runtime_switchToContext (JNIEnv *env, jint contextID); - void Java_mono_android_Runtime_destroyContexts (JNIEnv *env, jintArray array); - void shutdown_android_runtime (MonoDomain *domain); -#endif + jint Java_JNI_OnLoad (JavaVM *vm, void *reserved); static bool is_startup_in_progress () noexcept @@ -217,52 +188,19 @@ namespace xamarin::android::internal monodroid_gdb_wait = yes_no; } -#if defined (NET) void propagate_uncaught_exception (JNIEnv *env, jobject javaThread, jthrowable javaException); -#else // def NET - void propagate_uncaught_exception (MonoDomain *domain, JNIEnv *env, jobject javaThread, jthrowable javaException); - - FILE *get_counters () const - { - return counters; - } - - // The reason we don't use the C++ overload feature here is that there appears to be an issue in clang++ that - // comes with the Android NDK. The issue is that for calls like: - // - // char *s = "something"; - // dump_counters ("My string: %s", s); - // - // the compiler will resolve the overload taking `va_list` instead of the one with the ellipsis, thus causing - // `vfprintf` to segfault while trying to perform a `strlen` on `args`. - // - // The issue appears to stem from the fact that `va_list` in the NDK is a typedef to `__builtin_va_list` which - // in turn is internally defined by clang to be `char*` - // - // Desktop builds (using both clang++ and g++) do NOT appear to have this issue, so it might be a problem in the - // NDK. More investigation would be required, but for now lets work around the issue by not overloading the - // function - void dump_counters (const char *format, ...); - void dump_counters_v (const char *format, va_list args); -#endif // ndef NET - char* get_java_class_name_for_TypeManager (jclass klass); private: -#if defined (ANDROID) 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 (); -#endif // def ANDROID unsigned int convert_dl_flags (int flags); -#if defined (WINDOWS) || defined (APPLE_OS_X) - static const char* get_my_location (bool remove_file_name = true); -#endif // defined(WINDOWS) || defined(APPLE_OS_X) -#if defined (NET) + static void cleanup_runtime_config (MonovmRuntimeConfigArguments *args, void *user_data); static void* load_library_symbol (const char *library_name, const char *symbol_name, void **dso_handle = nullptr) noexcept; static void* load_library_entry (std::string const& library_name, std::string const& entrypoint_name, pinvoke_api_map_ptr api_map) noexcept; @@ -271,40 +209,26 @@ namespace xamarin::android::internal static PinvokeEntry* find_pinvoke_address (hash_t hash, const PinvokeEntry *entries, size_t entry_count) noexcept; static void* handle_other_pinvoke_request (const char *library_name, hash_t library_name_hash, const char *entrypoint_name, hash_t entrypoint_name_hash) noexcept; static void* monodroid_pinvoke_override (const char *library_name, const char *entrypoint_name); -#endif // def NET static void* monodroid_dlopen_ignore_component_or_load (hash_t hash, const char *name, int flags, char **err) noexcept; static void* monodroid_dlopen (const char *name, int flags, char **err) noexcept; static void* monodroid_dlopen (const char *name, int flags, char **err, void *user_data) noexcept; static void* monodroid_dlsym (void *handle, const char *name, char **err, void *user_data); static void* monodroid_dlopen_log_and_return (void *handle, char **err, const char *full_name, bool free_memory, bool need_api_init = false); static DSOCacheEntry* find_dso_cache_entry (hash_t hash) noexcept; -#if !defined (NET) - static void init_internal_api_dso (void *handle); -#endif // ndef NET + int LocalRefsAreIndirect (JNIEnv *env, jclass runtimeClass, int version); - void create_xdg_directory (jstring_wrapper& home, size_t home_len, const char *relativePath, size_t relative_path_len, const char *environmentVariableName); + 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 disable_external_signal_handlers (); void lookup_bridge_info (MonoClass *klass, const OSBridge::MonoJavaGCBridgeType *type, OSBridge::MonoJavaGCBridgeInfo *info); -#if defined (NET) void lookup_bridge_info (MonoImage *image, const OSBridge::MonoJavaGCBridgeType *type, OSBridge::MonoJavaGCBridgeInfo *info); -#else // def NET - void lookup_bridge_info (MonoDomain *domain, MonoImage *image, const OSBridge::MonoJavaGCBridgeType *type, OSBridge::MonoJavaGCBridgeInfo *info); -#endif // ndef NET void load_assembly (MonoDomain *domain, jstring_wrapper &assembly); -#if defined (NET) void load_assembly (MonoAssemblyLoadContextGCHandle alc_handle, jstring_wrapper &assembly); -#endif // ndef NET 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); -#if defined (NET) void init_android_runtime (JNIEnv *env, jclass runtimeClass, jobject loader); -#else //def NET - void init_android_runtime (MonoDomain *domain, JNIEnv *env, jclass runtimeClass, jobject loader); -#endif // ndef NET 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) @@ -317,13 +241,9 @@ namespace xamarin::android::internal set_environment_variable_for_directory (name, value, false, 0); } -#if defined (NET) static void monodroid_unhandled_exception (MonoObject *java_exception); - MonoClass* get_android_runtime_class (); -#else // def NET - MonoClass* get_android_runtime_class (MonoDomain *domain); -#endif + 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, jstring_array_wrapper &assemblies, jobjectArray assembliesBytes, jstring_array_wrapper &assembliesPaths, @@ -341,15 +261,14 @@ namespace xamarin::android::internal static void jit_done (MonoProfiler *prof, MonoMethod *method, MonoJitInfo* jinfo); static void thread_start (MonoProfiler *prof, uintptr_t tid); static void thread_end (MonoProfiler *prof, uintptr_t tid); -#if !defined (RELEASE) || !defined (ANDROID) +#if !defined (RELEASE) static MonoReflectionType* typemap_java_to_managed (MonoString *java_type_name) noexcept; static const char* typemap_managed_to_java (MonoReflectionType *type, const uint8_t *mvid) noexcept; -#endif // !def RELEASE || !def ANDROID +#endif // !def RELEASE -#if defined (NET) static void monodroid_debugger_unhandled_exception (MonoException *ex); -#if defined (RELEASE) && defined (ANDROID) +#if defined (RELEASE) static const char* get_method_name (uint32_t mono_image_index, uint32_t method_token) noexcept; static const char* get_class_name (uint32_t class_index) noexcept; @@ -357,17 +276,13 @@ namespace xamarin::android::internal static void get_function_pointer (uint32_t mono_image_index, uint32_t class_index, uint32_t method_token, void*& target_ptr) noexcept; static void get_function_pointer_at_startup (uint32_t mono_image_index, uint32_t class_token, uint32_t method_token, void*& target_ptr) noexcept; static void get_function_pointer_at_runtime (uint32_t mono_image_index, uint32_t class_token, uint32_t method_token, void*& target_ptr) noexcept; -#endif // def RELEASE && def ANDROID -#endif // def NET +#endif // def RELEASE #if defined (DEBUG) void set_debug_env_vars (void); - -#if !defined (WINDOWS) 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); -#endif // !WINDOWS #endif // DEBUG #if !defined (RELEASE) @@ -384,9 +299,6 @@ namespace xamarin::android::internal timing_period jit_time; FILE *jit_log; MonoProfilerHandle profiler_handle; -#if !defined (NET) - FILE *counters; -#endif // ndef NET /* * If set, monodroid will spin in a loop until the debugger breaks the wait by @@ -402,10 +314,7 @@ namespace xamarin::android::internal int current_context_id = -1; static bool startup_in_progress; -#if defined (NET) -#if defined (ANDROID) jnienv_register_jni_natives_fn jnienv_register_jni_natives = nullptr; -#endif MonoAssemblyLoadContextGCHandle default_alc = nullptr; static std::mutex pinvoke_map_write_lock; @@ -416,10 +325,6 @@ namespace xamarin::android::internal static void *system_native_library_handle; static void *system_security_cryptography_native_android_library_handle; static void *system_io_compression_native_library_handle; -#else // def NET - static std::mutex api_init_lock; - static void *api_dso_handle; -#endif // !def NET static std::mutex dso_handle_write_lock; }; } diff --git a/src/monodroid/jni/monodroid-glue.cc b/src/monodroid/jni/monodroid-glue.cc index d5f8f5ae86d..60eeeacbab4 100644 --- a/src/monodroid/jni/monodroid-glue.cc +++ b/src/monodroid/jni/monodroid-glue.cc @@ -1,27 +1,27 @@ #include -#include -#include - -#include -#include -#include -#include -#include #include #include -#if !defined (__MINGW32__) || (defined (__MINGW32__) && __GNUC__ >= 10) #include -#endif // ndef MINGW32 || def MINGW32 && GNUC >= 10 -#if defined (APPLE_OS_X) -#include -#endif // def APPLE_OX_X - -#include -#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include +#include +#include + +#include #include #include @@ -34,48 +34,20 @@ #include #include -#if defined (NET) #include -#endif #include "mono_android_Runtime.h" -#if defined (DEBUG) && !defined (WINDOWS) -#include +#if defined (DEBUG) #include #include #include #endif -#if defined (__linux__) || defined (__linux) -#include -#endif - -#if defined (APPLE_OS_X) -#include -#endif // defined(APPLE_OS_X) - -#ifndef WINDOWS -#include -#include -#else -#include -#include -#include -#include -#include -#include -#endif - -#include -#include -#include -#include - -#include "java-interop-util.h" +//#include "java-interop-util.h" #include "logger.hh" -#include "monodroid.h" +//#include "monodroid.h" #include "util.hh" #include "debug.hh" #include "embedded-assemblies.hh" @@ -84,15 +56,13 @@ #include "globals.hh" #include "xamarin-app.hh" #include "timing.hh" -#include "xa-internal-api-impl.hh" +//#include "xa-internal-api-impl.hh" #include "build-info.hh" #include "monovm-properties.hh" #include "startup-aware-lock.hh" #include "timing-internal.hh" -#ifndef WINDOWS -#include "xamarin_getifaddrs.h" -#endif +//#include "xamarin_getifaddrs.h" #include "cpp-util.hh" #include "strings.hh" @@ -103,13 +73,6 @@ using namespace microsoft::java_interop; using namespace xamarin::android; using namespace xamarin::android::internal; -#if !defined (NET) -#include "config.include" -#include "machine.config.include" - -std::mutex MonodroidRuntime::api_init_lock; -void *MonodroidRuntime::api_dso_handle = nullptr; -#else // ndef NET std::mutex MonodroidRuntime::pinvoke_map_write_lock; MonoCoreRuntimeProperties MonodroidRuntime::monovm_core_properties = { @@ -119,67 +82,15 @@ MonoCoreRuntimeProperties MonodroidRuntime::monovm_core_properties = { .pinvoke_override = &MonodroidRuntime::monodroid_pinvoke_override }; -#endif // def NET - std::mutex MonodroidRuntime::dso_handle_write_lock; bool MonodroidRuntime::startup_in_progress = true; -#ifdef WINDOWS -static const char* get_xamarin_android_msbuild_path (void); -const char *BasicAndroidSystem::SYSTEM_LIB_PATH = get_xamarin_android_msbuild_path(); - -/* Set of Windows-specific utility/reimplementation of Unix functions */ - -static char *msbuild_folder_path = nullptr; - -static const char* -get_xamarin_android_msbuild_path (void) -{ - const char *suffix = "MSBuild\\Xamarin\\Android"; - char *base_path = nullptr; - wchar_t *buffer = nullptr; - - if (msbuild_folder_path != nullptr) - return msbuild_folder_path; - - // Get the base path for 'Program Files' on Windows - if (!SUCCEEDED (SHGetKnownFolderPath (FOLDERID_ProgramFilesX86, 0, nullptr, &buffer))) { - if (buffer != nullptr) - CoTaskMemFree (buffer); - // returns current directory if a global one couldn't be found - return "."; - } - - // Compute the final path - base_path = utils.utf16_to_utf8 (buffer); - if (base_path == nullptr) { - log_fatal (LOG_DEFAULT, "Failed to convert UTF-16 to UTF-8 in %s", __PRETTY_FUNCTION__); - Helpers::abort_application (); - } - CoTaskMemFree (buffer); - msbuild_folder_path = utils.path_combine (base_path, suffix); - free (base_path); - - return msbuild_folder_path; -} - -static int -setenv(const char *name, const char *value, int overwrite) -{ - return androidSystem.setenv (name, value, overwrite); -} -#endif // def WINDOWS - void MonodroidRuntime::thread_start ([[maybe_unused]] MonoProfiler *prof, [[maybe_unused]] uintptr_t tid) { JNIEnv* env; - int r; -#ifdef PLATFORM_ANDROID - r = osBridge.get_jvm ()->AttachCurrentThread (&env, nullptr); -#else // ndef PLATFORM_ANDROID - r = osBridge.get_jvm ()->AttachCurrentThread (reinterpret_cast(&env), nullptr); -#endif // ndef PLATFORM_ANDROID + int r = osBridge.get_jvm ()->AttachCurrentThread (&env, nullptr); + if (r != JNI_OK) { #if DEBUG log_fatal (LOG_DEFAULT, "ERROR: Unable to attach current thread to the Java VM!"); @@ -191,8 +102,7 @@ MonodroidRuntime::thread_start ([[maybe_unused]] MonoProfiler *prof, [[maybe_unu void MonodroidRuntime::thread_end ([[maybe_unused]] MonoProfiler *prof, [[maybe_unused]] uintptr_t tid) { - int r; - r = osBridge.get_jvm ()->DetachCurrentThread (); + int r = osBridge.get_jvm ()->DetachCurrentThread (); if (r != JNI_OK) { #if DEBUG /* @@ -240,35 +150,6 @@ MonodroidRuntime::jit_done ([[maybe_unused]] MonoProfiler *prof, MonoMethod *met MonoAssembly* MonodroidRuntime::open_from_update_dir (MonoAssemblyName *aname, [[maybe_unused]] char **assemblies_path, [[maybe_unused]] void *user_data) { - MonoAssembly *result = nullptr; - -#ifndef ANDROID - // First check if there are any in-memory assemblies - if (designerAssemblies.has_assemblies ()) { - MonoDomain *domain = mono_domain_get (); - result = designerAssemblies.try_load_assembly (domain, aname); - if (result != nullptr) { - log_debug (LOG_ASSEMBLY, "Loaded assembly %s from memory in domain %d", mono_assembly_name_get_name (aname), mono_domain_get_id (domain)); - return result; - } - log_debug (LOG_ASSEMBLY, "No in-memory data found for assembly %s", mono_assembly_name_get_name (aname)); - } else { - log_debug (LOG_ASSEMBLY, "No in-memory assemblies detected", mono_assembly_name_get_name (aname)); - } -#endif - const char *override_dir; - bool found = false; - - for (uint32_t oi = 0; oi < AndroidSystem::MAX_OVERRIDES; ++oi) { - override_dir = androidSystem.get_override_dir (oi); - if (override_dir != nullptr && utils.directory_exists (override_dir)) { - found = true; - break; - } - } - if (!found) - return nullptr; - const char *culture = reinterpret_cast (mono_assembly_name_get_culture (aname)); const char *name = reinterpret_cast (mono_assembly_name_get_name (aname)); size_t culture_len; @@ -286,23 +167,22 @@ MonodroidRuntime::open_from_update_dir (MonoAssemblyName *aname, [[maybe_unused] } pname.append (name, name_len); - constexpr size_t dll_extension_len = sizeof(SharedConstants::DLL_EXTENSION) - 1; - bool is_dll = utils.ends_with (name, SharedConstants::DLL_EXTENSION); size_t file_name_len = pname.length () + 1; if (!is_dll) - file_name_len += dll_extension_len; + file_name_len += SharedConstants::DLL_EXTENSION.length (); - for (uint32_t oi = 0; oi < AndroidSystem::MAX_OVERRIDES; ++oi) { - override_dir = androidSystem.get_override_dir (oi); - if (override_dir == nullptr || !utils.directory_exists (override_dir)) + MonoAssembly *result = nullptr; + for (const char *override_dir : AndroidSystem::override_dirs) { + if (override_dir == nullptr || !utils.directory_exists (override_dir)) { continue; + } size_t override_dir_len = strlen (override_dir); static_local_string fullpath (override_dir_len + file_name_len); utils.path_combine (fullpath, override_dir, override_dir_len, pname.get (), pname.length ()); if (!is_dll) { - fullpath.append (SharedConstants::DLL_EXTENSION, dll_extension_len); + fullpath.append (SharedConstants::DLL_EXTENSION); } log_info (LOG_ASSEMBLY, "open_from_update_dir: trying to open assembly: %s\n", fullpath.get ()); @@ -330,10 +210,10 @@ MonodroidRuntime::should_register_file ([[maybe_unused]] const char *filename) } size_t filename_len = strlen (filename) + 1; // includes space for path separator - for (size_t i = 0; i < AndroidSystem::MAX_OVERRIDES; ++i) { - const char *odir = androidSystem.get_override_dir (i); - if (odir == nullptr) + for (const char *odir : AndroidSystem::override_dirs) { + if (odir == nullptr) { continue; + } size_t odir_len = strlen (odir); static_local_string p (odir_len + filename_len); @@ -352,14 +232,14 @@ 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) { -#if defined(DEBUG) || !defined (ANDROID) +#if defined(DEBUG) if (application_config.instant_run_enabled) { - for (size_t i = 0; i < AndroidSystem::MAX_OVERRIDES; ++i) { - const char *p = androidSystem.get_override_dir (i); - if (p == nullptr || !utils.directory_exists (p)) + for (const char *od : AndroidSystem::override_dirs) { + if (od == nullptr || !utils.directory_exists (od)) { continue; - log_info (LOG_ASSEMBLY, "Loading TypeMaps from %s", p); - embeddedAssemblies.try_load_typemaps_from_directory (p); + } + log_info (LOG_ASSEMBLY, "Loading TypeMaps from %s", od); + embeddedAssemblies.try_load_typemaps_from_directory (od); } } #endif @@ -399,7 +279,7 @@ MonodroidRuntime::gather_bundled_assemblies (jstring_array_wrapper &runtimeApks, embeddedAssemblies.ensure_valid_assembly_stores (); } -#if defined (DEBUG) && !defined (WINDOWS) +#if defined (DEBUG) int MonodroidRuntime::monodroid_debug_connect (int sock, struct sockaddr_in addr) { @@ -494,9 +374,7 @@ MonodroidRuntime::parse_gdb_options () if (!(androidSystem.monodroid_get_system_property (Debug::DEBUG_MONO_GDB_PROPERTY, val) > 0)) return; - constexpr char wait_param[] = "wait:"; - constexpr size_t wait_param_length = sizeof(wait_param) - 1; - + constexpr std::string_view wait_param { "wait:" }; if (val.starts_with (wait_param)) { /* * The form of the property should be: 'wait:', where should be @@ -507,12 +385,12 @@ MonodroidRuntime::parse_gdb_options () */ bool do_wait = true; - long long v = atoll (val.get () + wait_param_length); + long long v = atoll (val.get () + wait_param.length ()); if (v > 100000) { time_t secs = time (nullptr); if (v + 10 < secs) { - log_warn (LOG_DEFAULT, "Found stale %s property with value '%s', not waiting.", Debug::DEBUG_MONO_GDB_PROPERTY, val.get ()); + log_warn (LOG_DEFAULT, "Found stale %s property with value '%s', not waiting.", Debug::DEBUG_MONO_GDB_PROPERTY.data (), val.get ()); do_wait = false; } } @@ -521,7 +399,7 @@ MonodroidRuntime::parse_gdb_options () } } -#if defined (DEBUG) && !defined (WINDOWS) +#if defined (DEBUG) bool MonodroidRuntime::parse_runtime_args (dynamic_local_string &runtime_args, RuntimeOptions *options) { @@ -530,26 +408,22 @@ MonodroidRuntime::parse_runtime_args (dynamic_local_stringhost = host; options->sdb_port = static_cast(sdb_port); options->out_port = out_port == -1 ? 0 : static_cast(out_port); - } else if (token.starts_with (ARG_TIMEOUT, ARG_TIMEOUT_LENGTH)) { - if (!token.to_integer (options->timeout_time, ARG_TIMEOUT_LENGTH)) { + } else if (token.starts_with (ARG_TIMEOUT)) { + if (!token.to_integer (options->timeout_time, ARG_TIMEOUT.length ())) { log_error (LOG_DEFAULT, "Invalid --timeout argument."); ret = false; } - } else if (token.starts_with (ARG_SERVER, ARG_SERVER_LENGTH)) { - options->server = token.has_at ('y', ARG_SERVER_LENGTH) || token.has_at ('Y', ARG_SERVER_LENGTH); - } else if (token.starts_with (ARG_LOGLEVEL, ARG_LOGLEVEL_LENGTH)) { - if (!token.to_integer (options->loglevel, ARG_LOGLEVEL_LENGTH)) { + } else if (token.starts_with (ARG_SERVER)) { + options->server = token.has_at ('y', ARG_SERVER.length ()) || token.has_at ('Y', ARG_SERVER.length ()); + } else if (token.starts_with (ARG_LOGLEVEL)) { + if (!token.to_integer (options->loglevel, ARG_LOGLEVEL.length ())) { log_error (LOG_DEFAULT, "Invalid --loglevel argument."); ret = false; } @@ -640,7 +514,7 @@ MonodroidRuntime::set_debug_options (void) void MonodroidRuntime::mono_runtime_init ([[maybe_unused]] JNIEnv *env, [[maybe_unused]] dynamic_local_string& runtime_args) { -#if defined (DEBUG) && !defined (WINDOWS) +#if defined (DEBUG) RuntimeOptions options{}; int64_t cur_time; @@ -721,8 +595,8 @@ MonodroidRuntime::mono_runtime_init ([[maybe_unused]] JNIEnv *env, [[maybe_unuse } if (debug.enable_soft_breakpoints ()) { - constexpr char soft_breakpoints[] = "--soft-breakpoints"; - debug_options[1] = const_cast (soft_breakpoints); + constexpr std::string_view soft_breakpoints { "--soft-breakpoints" }; + debug_options[1] = const_cast (soft_breakpoints.data ()); mono_jit_parse_options (2, debug_options); } else { mono_jit_parse_options (1, debug_options); @@ -747,8 +621,8 @@ MonodroidRuntime::mono_runtime_init ([[maybe_unused]] JNIEnv *env, [[maybe_unuse //log_warn (LOG_DEFAULT, "Let us have an overflow: %d", INT_MAX + 1); bool log_methods = FastTiming::enabled () && !FastTiming::is_bare_mode (); - if (XA_UNLIKELY (log_methods)) { - std::unique_ptr jit_log_path {utils.path_combine (androidSystem.get_override_dir (0), "methods.txt")}; + if (log_methods) [[unlikely]] { + std::unique_ptr jit_log_path {utils.path_combine (AndroidSystem::override_dirs [0], "methods.txt")}; jit_log = utils.monodroid_fopen (jit_log_path.get (), "a"); utils.set_world_accessable (jit_log_path.get ()); } @@ -757,7 +631,7 @@ MonodroidRuntime::mono_runtime_init ([[maybe_unused]] JNIEnv *env, [[maybe_unuse mono_profiler_set_thread_started_callback (profiler_handle, thread_start); mono_profiler_set_thread_stopped_callback (profiler_handle, thread_end); - if (XA_UNLIKELY (log_methods)) { + if (log_methods) [[unlikely]]{ jit_time.mark_start (); mono_profiler_set_jit_begin_callback (profiler_handle, jit_begin); mono_profiler_set_jit_done_callback (profiler_handle, jit_done); @@ -808,14 +682,13 @@ MonodroidRuntime::mono_runtime_init ([[maybe_unused]] JNIEnv *env, [[maybe_unuse mono_install_assembly_preload_hook (open_from_update_dir, nullptr); #endif -#if defined (RELEASE) && defined (ANDROID) && defined (NET) +#if defined (RELEASE) if (application_config.marshal_methods_enabled) { xamarin_app_init (env, get_function_pointer_at_startup); } #endif // def RELEASE && def ANDROID && def NET } -#if defined (NET) void MonodroidRuntime::cleanup_runtime_config (MonovmRuntimeConfigArguments *args, [[maybe_unused]] void *user_data) { @@ -823,11 +696,8 @@ MonodroidRuntime::cleanup_runtime_config (MonovmRuntimeConfigArguments *args, [[ return; } -#if !defined (WINDOWS) munmap (static_cast(const_cast(args->runtimeconfig.data.data)), args->runtimeconfig.data.data_len); -#endif // ndef WINDOWS } -#endif // def NET MonoDomain* MonodroidRuntime::create_domain (JNIEnv *env, jstring_array_wrapper &runtimeApks, bool is_root_domain, bool have_split_apks) @@ -836,9 +706,8 @@ MonodroidRuntime::create_domain (JNIEnv *env, jstring_array_wrapper &runtimeApks gather_bundled_assemblies (runtimeApks, &user_assemblies_count, have_split_apks); -#if defined (NET) size_t blob_time_index; - if (XA_UNLIKELY (FastTiming::enabled ())) { + if (FastTiming::enabled ()) [[unlikely]] { blob_time_index = internal_timing->start_event (TimingEventKind::RuntimeConfigBlob); } @@ -848,16 +717,15 @@ MonodroidRuntime::create_domain (JNIEnv *env, jstring_array_wrapper &runtimeApks monovm_runtimeconfig_initialize (&runtime_config_args, cleanup_runtime_config, nullptr); } - if (XA_UNLIKELY (FastTiming::enabled ())) { + if (FastTiming::enabled ()) [[unlikely]] { internal_timing->end_event (blob_time_index); } -#endif // def NET if (user_assemblies_count == 0 && androidSystem.count_override_assemblies () == 0 && !is_running_on_desktop) { #if defined (DEBUG) log_fatal (LOG_DEFAULT, "No assemblies found in '%s' or '%s'. Assuming this is part of Fast Deployment. Exiting...", - androidSystem.get_override_dir (0), - (AndroidSystem::MAX_OVERRIDES > 1 && androidSystem.get_override_dir (1) != nullptr) ? androidSystem.get_override_dir (1) : ""); + AndroidSystem::override_dirs [0], + (AndroidSystem::override_dirs.size () > 1 && AndroidSystem::override_dirs [1] != nullptr) ? AndroidSystem::override_dirs [1] : ""); #else log_fatal (LOG_DEFAULT, "No assemblies (or assembly blobs) were found in the application APK file(s)"); #endif @@ -867,27 +735,7 @@ MonodroidRuntime::create_domain (JNIEnv *env, jstring_array_wrapper &runtimeApks Helpers::abort_application (); } - MonoDomain *domain; -#if !defined (NET) - if (is_root_domain) { -#endif // ndef NET - domain = mono_jit_init_version (const_cast ("RootDomain"), const_cast ("mobile")); -#if !defined (NET) - } else { - MonoDomain* root_domain = mono_get_root_domain (); - - constexpr char DOMAIN_NAME[] = "MonoAndroidDomain"; - constexpr size_t DOMAIN_NAME_LENGTH = sizeof(DOMAIN_NAME) - 1; - constexpr size_t DOMAIN_NAME_TOTAL_SIZE = DOMAIN_NAME_LENGTH + SharedConstants::MAX_INTEGER_DIGIT_COUNT_BASE10; - - static_local_string domain_name (DOMAIN_NAME_TOTAL_SIZE); - domain_name.append (DOMAIN_NAME); - domain_name.append (android_api_level); - - domain = utils.monodroid_create_appdomain (root_domain, domain_name.get (), /*shadow_copy:*/ 1, /*shadow_directory:*/ androidSystem.get_override_dir (0)); - } -#endif // ndef NET - + MonoDomain *domain = mono_jit_init_version (const_cast ("RootDomain"), const_cast ("mobile")); if constexpr (is_running_on_desktop) { if (is_root_domain) { c_unique_ptr corlib_error_message_guard {const_cast(mono_check_corlib_version ())}; @@ -950,7 +798,6 @@ MonodroidRuntime::lookup_bridge_info (MonoClass *klass, const OSBridge::MonoJava } } -#if defined (NET) force_inline void MonodroidRuntime::lookup_bridge_info (MonoImage *image, const OSBridge::MonoJavaGCBridgeType *type, OSBridge::MonoJavaGCBridgeInfo *info) { @@ -960,53 +807,34 @@ MonodroidRuntime::lookup_bridge_info (MonoImage *image, const OSBridge::MonoJava info ); } -#else // def NET -force_inline void -MonodroidRuntime::lookup_bridge_info (MonoDomain *domain, MonoImage *image, const OSBridge::MonoJavaGCBridgeType *type, OSBridge::MonoJavaGCBridgeInfo *info) -{ - lookup_bridge_info ( - utils.monodroid_get_class_from_image (domain, image, type->_namespace, type->_typename), - type, - info - ); -} -#endif // ndef NET -#if defined (NET) void MonodroidRuntime::monodroid_debugger_unhandled_exception (MonoException *ex) { mono_debugger_agent_unhandled_exception (ex); } -#endif void -MonodroidRuntime::init_android_runtime ( -#if !defined (NET) - MonoDomain *domain, -#endif // ndef NET - JNIEnv *env, jclass runtimeClass, jobject loader) +MonodroidRuntime::init_android_runtime (JNIEnv *env, jclass runtimeClass, jobject loader) { - constexpr char icall_typemap_java_to_managed[] = "Java.Interop.TypeManager::monodroid_typemap_java_to_managed"; - constexpr char icall_typemap_managed_to_java[] = "Android.Runtime.JNIEnv::monodroid_typemap_managed_to_java"; + 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" }; -#if defined (RELEASE) && defined (ANDROID) +#if defined (RELEASE) // The reason for these using is that otherwise the compiler will complain about not being // able to cast overloaded methods to const void* pointers. using j2mFn = MonoReflectionType* (*)(MonoString *java_type); using m2jFn = const char* (*)(MonoReflectionType *type, const uint8_t *mvid); - mono_add_internal_call (icall_typemap_java_to_managed, reinterpret_cast(static_cast(EmbeddedAssemblies::typemap_java_to_managed))); - mono_add_internal_call (icall_typemap_managed_to_java, reinterpret_cast(static_cast(EmbeddedAssemblies::typemap_managed_to_java))); + mono_add_internal_call (icall_typemap_java_to_managed.data (), reinterpret_cast(static_cast(EmbeddedAssemblies::typemap_java_to_managed))); + mono_add_internal_call (icall_typemap_managed_to_java.data (), reinterpret_cast(static_cast(EmbeddedAssemblies::typemap_managed_to_java))); #else - mono_add_internal_call (icall_typemap_java_to_managed, reinterpret_cast(typemap_java_to_managed)); - mono_add_internal_call (icall_typemap_managed_to_java, reinterpret_cast(typemap_managed_to_java)); + mono_add_internal_call (icall_typemap_java_to_managed.data (), reinterpret_cast(typemap_java_to_managed)); + mono_add_internal_call (icall_typemap_managed_to_java.data (), reinterpret_cast(typemap_managed_to_java)); #endif // def RELEASE && def ANDROID -#if defined (NET) mono_add_internal_call ("Android.Runtime.RuntimeNativeMethods::monodroid_debugger_unhandled_exception", reinterpret_cast (monodroid_debugger_unhandled_exception)); mono_add_internal_call ("Android.Runtime.RuntimeNativeMethods::monodroid_unhandled_exception", reinterpret_cast(monodroid_unhandled_exception)); -#endif // def NET struct JnienvInitializeArgs init = {}; init.javaVm = osBridge.get_jvm (); @@ -1034,19 +862,12 @@ MonodroidRuntime::init_android_runtime ( MonoAssembly *mono_android_assembly; -#if defined (NET) - mono_android_assembly = utils.monodroid_load_assembly (default_alc, SharedConstants::MONO_ANDROID_ASSEMBLY_NAME); -#else // def NET - mono_android_assembly = utils.monodroid_load_assembly (domain, SharedConstants::MONO_ANDROID_ASSEMBLY_NAME); -#endif // ndef NET + mono_android_assembly = utils.monodroid_load_assembly (default_alc, SharedConstants::MONO_ANDROID_ASSEMBLY_NAME.data ()); MonoImage *mono_android_assembly_image = mono_assembly_get_image (mono_android_assembly); uint32_t i = 0; for ( ; i < OSBridge::NUM_XA_GC_BRIDGE_TYPES; ++i) { lookup_bridge_info ( -#if !defined (NET) - domain, -#endif // ndef NET mono_android_assembly_image, &osBridge.get_java_gc_bridge_type (i), &osBridge.get_java_gc_bridge_info (i) @@ -1057,11 +878,7 @@ MonodroidRuntime::init_android_runtime ( MonoMethod *method; if constexpr (is_running_on_desktop) { -#if defined (NET) - runtime = mono_class_from_name (mono_android_assembly_image, SharedConstants::ANDROID_RUNTIME_NS_NAME, SharedConstants::JNIENVINIT_CLASS_NAME); -#else - runtime = utils.monodroid_get_class_from_image (domain, mono_android_assembly_image, SharedConstants::ANDROID_RUNTIME_NS_NAME, SharedConstants::JNIENVINIT_CLASS_NAME); -#endif // def NET + runtime = mono_class_from_name (mono_android_assembly_image, SharedConstants::ANDROID_RUNTIME_NS_NAME.data (), SharedConstants::JNIENVINIT_CLASS_NAME.data ()); method = mono_class_get_method_from_name (runtime, "Initialize", 1); } else { runtime = mono_class_get (mono_android_assembly_image, application_config.android_runtime_jnienv_class_token); @@ -1072,18 +889,11 @@ MonodroidRuntime::init_android_runtime ( abort_unless (method != nullptr, "INTERNAL ERROR: Unable to find the Android.Runtime.JNIEnvInit.Initialize method!"); MonoAssembly *ji_assm; -#if defined (NET) - ji_assm = utils.monodroid_load_assembly (default_alc, SharedConstants::JAVA_INTEROP_ASSEMBLY_NAME); -#else // def NET - ji_assm = utils.monodroid_load_assembly (domain, SharedConstants::JAVA_INTEROP_ASSEMBLY_NAME); -#endif // ndef NET + ji_assm = utils.monodroid_load_assembly (default_alc, SharedConstants::JAVA_INTEROP_ASSEMBLY_NAME.data ()); MonoImage *ji_image = mono_assembly_get_image (ji_assm); for ( ; i < OSBridge::NUM_XA_GC_BRIDGE_TYPES + OSBridge::NUM_JI_GC_BRIDGE_TYPES; ++i) { lookup_bridge_info ( -#if !defined (NET) - domain, -#endif // ndef NET ji_image, &osBridge.get_java_gc_bridge_type (i), &osBridge.get_java_gc_bridge_info (i) @@ -1099,9 +909,7 @@ MonodroidRuntime::init_android_runtime ( registerType = mono_class_get_method_from_name (runtime, "RegisterJniNatives", 5); } else { registerType = mono_get_method (mono_android_assembly_image, application_config.jnienv_registerjninatives_method_token, runtime); -#if defined (NET) && defined (ANDROID) jnienv_register_jni_natives = reinterpret_cast(mono_method_get_unmanaged_callers_only_ftnptr (registerType, &error)); -#endif // def NET && def ANDROID } } abort_unless (registerType != nullptr, "INTERNAL ERROR: Unable to find Android.Runtime.JNIEnvInit.RegisterJniNatives! %s", mono_error_get_message (&error)); @@ -1118,11 +926,10 @@ MonodroidRuntime::init_android_runtime ( log_debug (LOG_DEFAULT, "Calling into managed runtime init"); size_t native_to_managed_index; - if (XA_UNLIKELY (FastTiming::enabled ())) { + if (FastTiming::enabled ()) [[unlikely]] { native_to_managed_index = internal_timing->start_event (TimingEventKind::NativeToManagedTransition); } -#if defined (NET) && defined (ANDROID) auto initialize = reinterpret_cast (mono_method_get_unmanaged_callers_only_ftnptr (method, &error)); if (initialize == nullptr) { log_fatal (LOG_DEFAULT, "Failed to get pointer to Initialize. Mono error: %s", mono_error_get_message (&error)); @@ -1134,50 +941,24 @@ MonodroidRuntime::init_android_runtime ( mono_error_get_message (&error) ); initialize (&init); -#else // def NET && def ANDROID - void *args [] = { - &init, - }; - - utils.monodroid_runtime_invoke (domain, method, nullptr, args, nullptr); -#endif // ndef NET && ndef ANDROID - if (XA_UNLIKELY (FastTiming::enabled ())) { + if (FastTiming::enabled ()) [[unlikely]] { internal_timing->end_event (native_to_managed_index); } } -#if defined (NET) MonoClass* MonodroidRuntime::get_android_runtime_class () { - MonoAssembly *assm = utils.monodroid_load_assembly (default_alc, SharedConstants::MONO_ANDROID_ASSEMBLY_NAME); + MonoAssembly *assm = utils.monodroid_load_assembly (default_alc, SharedConstants::MONO_ANDROID_ASSEMBLY_NAME.data ()); MonoImage *image = mono_assembly_get_image (assm); - return mono_class_from_name (image, SharedConstants::ANDROID_RUNTIME_NS_NAME, SharedConstants::JNIENV_CLASS_NAME); + return mono_class_from_name (image, SharedConstants::ANDROID_RUNTIME_NS_NAME.data (), SharedConstants::JNIENV_CLASS_NAME.data ()); } -#else // def NET -MonoClass* -MonodroidRuntime::get_android_runtime_class (MonoDomain *domain) -{ - MonoAssembly *assm = utils.monodroid_load_assembly (domain, SharedConstants::MONO_ANDROID_ASSEMBLY_NAME); - MonoImage *image = mono_assembly_get_image (assm); - return utils.monodroid_get_class_from_image (domain, image, SharedConstants::ANDROID_RUNTIME_NS_NAME, SharedConstants::JNIENV_CLASS_NAME); -} -#endif // ndef NET inline void -MonodroidRuntime::propagate_uncaught_exception ( -#if !defined (NET) - MonoDomain *domain, -#endif // ndef NET - JNIEnv *env, jobject javaThread, jthrowable javaException) +MonodroidRuntime::propagate_uncaught_exception (JNIEnv *env, jobject javaThread, jthrowable javaException) { - MonoClass *runtime; -#if defined (NET) - runtime = get_android_runtime_class (); -#else - runtime = get_android_runtime_class (domain); -#endif + MonoClass *runtime = get_android_runtime_class (); MonoMethod *method = mono_class_get_method_from_name (runtime, "PropagateUncaughtException", 3); void* args[] = { @@ -1185,11 +966,7 @@ MonodroidRuntime::propagate_uncaught_exception ( &javaThread, &javaException, }; -#if defined (NET) mono_runtime_invoke (method, nullptr, args, nullptr); -#else // def NET - utils.monodroid_runtime_invoke (domain, method, nullptr, args, nullptr); -#endif // ndef NET } #if DEBUG @@ -1212,60 +989,9 @@ MonodroidRuntime::convert_dl_flags (int flags) return lflags; } -#if !defined (NET) -force_inline void -MonodroidRuntime::init_internal_api_dso (void *handle) -{ - if (handle == nullptr) { - log_fatal (LOG_DEFAULT, "Internal API library is required"); - Helpers::abort_application (); - } - - // There's a very, very small chance of a race condition here, but it should be acceptable and we can save some time - // by not acquiring the lock on Android systems which don't have the dlopen bug we worked around in - // https://github.com/xamarin/xamarin-android/pull/4914 - // - // The race condition will exist only on systems with the above dynamic loader bug and would become a problem only - // if an application were loading managed assemblies with p/invokes very quickly from different threads. All in all, - // not a very likely scenario. - // - if (handle == api_dso_handle) { - log_debug (LOG_DEFAULT, "Internal API library already loaded, initialization not necessary"); - return; - } - - std::lock_guard lock (api_init_lock); - if (api_dso_handle != nullptr) { - auto api_shutdown = reinterpret_cast (java_interop_lib_symbol (api_dso_handle, MonoAndroidInternalCalls::SHUTDOWN_FUNCTION_NAME, nullptr)); - if (api_shutdown == nullptr) { - // We COULD ignore this situation, but if the function is missing it means we messed something up and thus - // it *is* a fatal error. - log_fatal (LOG_DEFAULT, "Unable to properly close Internal API library, shutdown function '%s' not found in the module", MonoAndroidInternalCalls::SHUTDOWN_FUNCTION_NAME); - Helpers::abort_application (); - } - api_shutdown (); - } - - api_dso_handle = handle; - auto api = new MonoAndroidInternalCalls_Impl (); - auto api_init = reinterpret_cast(java_interop_lib_symbol (handle, MonoAndroidInternalCalls::INIT_FUNCTION_NAME, nullptr)); - if (api_init == nullptr) { - log_fatal (LOG_DEFAULT, "Unable to initialize Internal API library, init function '%s' not found in the module", MonoAndroidInternalCalls::INIT_FUNCTION_NAME); - Helpers::abort_application (); - } - - log_debug (LOG_DEFAULT, "Initializing Internal API library %p", handle); - if (!api_init (api)) { - log_fatal (LOG_DEFAULT, "Failed to initialize Internal API library"); - Helpers::abort_application (); - } -} -#endif // ndef NET - force_inline DSOCacheEntry* MonodroidRuntime::find_dso_cache_entry ([[maybe_unused]] hash_t hash) noexcept { -#if !defined (__MINGW32__) || (defined (__MINGW32__) && __GNUC__ >= 10) hash_t entry_hash; DSOCacheEntry *ret = nullptr; size_t entry_count = application_config.number_of_dso_cache_entries; @@ -1285,7 +1011,6 @@ MonodroidRuntime::find_dso_cache_entry ([[maybe_unused]] hash_t hash) noexcept return ret; } } -#endif // ndef MINGW32 || def MINGW32 && GNUC >= 10 return nullptr; } @@ -1299,20 +1024,12 @@ MonodroidRuntime::monodroid_dlopen_log_and_return (void *handle, char **err, con if (free_memory) { delete[] full_name; } - -#if !defined (NET) - if (!need_api_init) - return handle; - init_internal_api_dso (handle); -#endif // ndef NET - return handle; } force_inline void* MonodroidRuntime::monodroid_dlopen_ignore_component_or_load ([[maybe_unused]] hash_t name_hash, const char *name, int flags, char **err) noexcept { -#if defined (NET) if (startup_in_progress) { auto ignore_component = [&](const char *label, MonoComponent component) -> bool { if ((application_config.mono_components_mask & component) != component) { @@ -1343,7 +1060,7 @@ MonodroidRuntime::monodroid_dlopen_ignore_component_or_load ([[maybe_unused]] ha break; } } -#endif + unsigned int dl_flags = monodroidRuntime.convert_dl_flags (flags); void * handle = androidSystem.load_dso_from_any_directories (name, dl_flags); if (handle != nullptr) { @@ -1389,117 +1106,12 @@ MonodroidRuntime::monodroid_dlopen (const char *name, int flags, char **err) noe void* MonodroidRuntime::monodroid_dlopen (const char *name, int flags, char **err, [[maybe_unused]] void *user_data) noexcept { - void *h = nullptr; - -#if defined (NET) if (name == nullptr) { log_warn (LOG_ASSEMBLY, "monodroid_dlopen got a null name. This is not supported in NET+"); return nullptr; } -#else // def NET - unsigned int dl_flags = monodroidRuntime.convert_dl_flags (flags); - - bool libmonodroid_fallback = false; - bool name_is_full_path = false; - bool name_needs_free = false; - /* name is nullptr when we're P/Invoking __Internal, so remap to libxa-internal-api */ - if (name == nullptr || strstr (name, "xa-internal-api") != nullptr) { -#if defined (WINDOWS) - char *tmp_name = nullptr; - - auto probe_dll_at = [&](const char *the_path) -> bool { - if (the_path == nullptr) { - return false; - } - - const char *last_sep = strrchr (the_path, MONODROID_PATH_SEPARATOR_CHAR); - if (last_sep != nullptr) { - char *dir = utils.strdup_new (the_path, last_sep - the_path); - if (dir == nullptr) { - return false; - } - - tmp_name = utils.string_concat (dir, MONODROID_PATH_SEPARATOR, API_DSO_NAME); - delete[] dir; - if (!utils.file_exists (tmp_name)) { - delete[] tmp_name; - tmp_name = nullptr; - return false; - } - - return true; - } - - return false; - }; - // - // First try to see if it exists at the path pointed to by `name`. With p/invokes, currently (Sep 2020), we can't - // really trust the path since it consists of *some* directory path + p/invoke library name and it does not - // point to the location where the native library is. However, we still need to check the location first, should - // it point to the right place in the future. - // - // Context: https://github.com/mono/mono/issues/20295#issuecomment-679271621 - // - bool found = probe_dll_at (name); - if (!found) { - // Next lets try the location of the XA runtime DLL, libxa-internal-api.dll should be next to it. - const char *path = get_my_location (false); - found = probe_dll_at (path); // lgtm [cpp/unguardednullreturndereference] probe_dll_at checks whether the passed pointer is nullptr - if (path != nullptr) { - free (reinterpret_cast(const_cast(path))); - } - - if (!found) { - log_warn (LOG_DEFAULT, "Failed to locate %s, using file name without the path", API_DSO_NAME); - name = API_DSO_NAME; - } else { - name = tmp_name; - name_is_full_path = true; - name_needs_free = true; - } - } -#else // ndef WINDOWS - name = API_DSO_NAME; -#endif // WINDOWS - libmonodroid_fallback = true; - } - - if (!name_is_full_path) { - // h = androidSystem.load_dso_from_any_directories (name, dl_flags); - h = monodroid_dlopen (name, flags, err); - if (h != nullptr) { - return h; // already logged by monodroid_dlopen - } - } - - if (h != nullptr) { - return monodroid_dlopen_log_and_return (h, err, name, name_needs_free, libmonodroid_fallback); - } - - if (libmonodroid_fallback) { - const char *full_name; - if (name_is_full_path) { - full_name = name; - } else { - if (name_needs_free) { - delete[] name; - } - full_name = utils.path_combine (AndroidSystem::SYSTEM_LIB_PATH, API_DSO_NAME); - name_needs_free = true; - } - h = androidSystem.load_dso (full_name, dl_flags, false); - return monodroid_dlopen_log_and_return (h, err, full_name, name_needs_free, true); - } -#endif // ndef NET - - h = monodroid_dlopen (name, flags, err); -#if !defined (NET) - if (name_needs_free) { - delete[] name; - } -#endif // ndef NET - return h; + return monodroid_dlopen (name, flags, err); } void* @@ -1532,16 +1144,17 @@ MonodroidRuntime::set_environment_variable_for_directory (const char *name, jstr } inline void -MonodroidRuntime::create_xdg_directory (jstring_wrapper& home, size_t home_len, const char *relativePath, size_t relative_path_len, const char *environmentVariableName) +MonodroidRuntime::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_local_string dir (home_len + relative_path_len); - utils.path_combine (dir, home.get_cstr (), home_len, relativePath, relative_path_len); + static_local_string dir (home_len + relative_path.length ()); + utils.path_combine (dir, home.get_cstr (), home_len, relative_path.data (), relative_path.length ()); log_debug (LOG_DEFAULT, "Creating XDG directory: %s", dir.get ()); int rv = utils.create_directory (dir.get (), DEFAULT_DIRECTORY_MODE); if (rv < 0 && errno != EEXIST) log_warn (LOG_DEFAULT, "Failed to create XDG directory %s. %s", dir.get (), strerror (errno)); - if (environmentVariableName) - setenv (environmentVariableName, dir.get (), 1); + if (!environment_variable_name.empty ()) { + setenv (environment_variable_name.data (), dir.get (), 1); + } } inline void @@ -1549,15 +1162,13 @@ MonodroidRuntime::create_xdg_directories_and_environment (jstring_wrapper &homeD { size_t home_len = strlen (homeDir.get_cstr ()); - constexpr char XDG_DATA_HOME[] = "XDG_DATA_HOME"; - constexpr char HOME_PATH[] = ".local/share"; - constexpr size_t HOME_PATH_LEN = sizeof(HOME_PATH) - 1; - create_xdg_directory (homeDir, home_len, HOME_PATH, HOME_PATH_LEN, XDG_DATA_HOME); + constexpr std::string_view XDG_DATA_HOME { "XDG_DATA_HOME" }; + constexpr std::string_view HOME_PATH { ".local/share" }; + create_xdg_directory (homeDir, home_len, HOME_PATH, XDG_DATA_HOME); - constexpr char XDG_CONFIG_HOME[] = "XDG_CONFIG_HOME"; - constexpr char CONFIG_PATH[] = ".config"; - constexpr size_t CONFIG_PATH_LEN = sizeof(CONFIG_PATH) - 1; - create_xdg_directory (homeDir, home_len, CONFIG_PATH, CONFIG_PATH_LEN, XDG_CONFIG_HOME); + constexpr std::string_view XDG_CONFIG_HOME { "XDG_CONFIG_HOME" }; + constexpr std::string_view CONFIG_PATH { ".config" }; + create_xdg_directory (homeDir, home_len, CONFIG_PATH, XDG_CONFIG_HOME); } #if DEBUG @@ -1581,12 +1192,12 @@ MonodroidRuntime::set_debug_env_vars (void) size_t index = static_cast(idx); if (idx < 0 || index == arg.length () - 1) { // ’name’ or ’name=’ - constexpr char one[] = "1"; + constexpr std::string_view one { "1" }; if (index == arg.length () - 1) { arg[index] = '\0'; } - setenv (arg.get (), one, 1); - log_envvar (arg.get (), one); + setenv (arg.get (), one.data (), 1); + log_envvar (arg.get (), one.data ()); } else if (index == 0) { // ’=value’ log_warn (LOG_DEFAULT, "Attempt to set environment variable without specifying name: '%s'", arg.get ()); @@ -1611,7 +1222,6 @@ MonodroidRuntime::set_trace_options (void) mono_jit_set_trace_options (value.get ()); } -#if defined (NET) inline void MonodroidRuntime::set_profile_options () { @@ -1628,16 +1238,15 @@ MonodroidRuntime::set_profile_options () // NET+ supports only the AOT Mono profiler, if the prefix is absent or different than 'aot:' we consider the // property to contain value for the dotnet tracing profiler. - constexpr char AOT_PREFIX[] = "aot:"; + constexpr std::string_view AOT_PREFIX { "aot:" }; if (!value.starts_with (AOT_PREFIX)) { // setenv(3) makes copies of its arguments setenv ("DOTNET_DiagnosticPorts", value.get (), 1); return; } - constexpr char OUTPUT_ARG[] = "output="; - constexpr size_t OUTPUT_ARG_LEN = sizeof(OUTPUT_ARG) - 1; - constexpr size_t start_index = sizeof(AOT_PREFIX); // one char past ':' + constexpr std::string_view OUTPUT_ARG { "output=" }; + constexpr size_t start_index = AOT_PREFIX.length () + 1; // one char past ':' dynamic_local_string output_path; bool have_output_arg = false; @@ -1650,18 +1259,18 @@ MonodroidRuntime::set_profile_options () continue; } - output_path.assign (param.start () + OUTPUT_ARG_LEN, param.length () - OUTPUT_ARG_LEN); + output_path.assign (param.start () + OUTPUT_ARG.length (), param.length () - OUTPUT_ARG.length ()); have_output_arg = true; break; } if (!have_output_arg) { - constexpr char PROFILE_FILE_NAME_PREFIX[] = "profile."; - constexpr char AOT_EXT[] = "aotprofile"; + constexpr std::string_view PROFILE_FILE_NAME_PREFIX { "profile." }; + constexpr std::string_view AOT_EXT { "aotprofile" }; output_path - .assign_c (androidSystem.get_override_dir (0)) - .append (MONODROID_PATH_SEPARATOR) + .assign_c (AndroidSystem::override_dirs [0]) + .append ("/") .append (PROFILE_FILE_NAME_PREFIX) .append (AOT_EXT); @@ -1674,143 +1283,17 @@ MonodroidRuntime::set_profile_options () log_warn (LOG_DEFAULT, "Initializing profiler with options: %s", value.get ()); debug.monodroid_profiler_load (androidSystem.get_runtime_libdir (), value.get (), output_path.get ()); } -#else // def NET -inline void -MonodroidRuntime::set_profile_options () -{ - // We want to avoid dynamic allocation, thus let’s create a buffer that can take both the property value and a - // path without allocation - dynamic_local_string value; - { - dynamic_local_string prop_value; - if (androidSystem.monodroid_get_system_property (Debug::DEBUG_MONO_PROFILE_PROPERTY, prop_value) == 0) - return; - - value.assign (prop_value.get (), prop_value.length ()); - } - constexpr char OUTPUT_ARG[] = "output="; - constexpr size_t OUTPUT_ARG_LEN = sizeof(OUTPUT_ARG) - 1; - - ssize_t colon_idx = value.index_of (':'); - size_t start_index = colon_idx < 0 ? 0 : static_cast(colon_idx + 1); - dynamic_local_string output_path; - bool have_output_arg = false; - string_segment param; - - while (value.next_token (start_index, ',', param)) { - dynamic_local_string temp; - temp.assign (param.start (), param.length ()); - if (!param.starts_with (OUTPUT_ARG) || param.length () == OUTPUT_ARG_LEN) { - continue; - } - - output_path.assign (param.start () + OUTPUT_ARG_LEN, param.length () - OUTPUT_ARG_LEN); - have_output_arg = true; - break; - } - - if (!have_output_arg) { - constexpr char MLPD_EXT[] = "mlpd"; - constexpr char AOT_EXT[] = "aotprofile"; - constexpr char COV_EXT[] = "xml"; - constexpr char LOG_PREFIX[] = "log:"; - constexpr size_t LOG_PREFIX_LENGTH = sizeof(LOG_PREFIX) - 1; - constexpr char AOT_PREFIX[] = "aot:"; - constexpr size_t AOT_PREFIX_LENGTH = sizeof(AOT_PREFIX) - 1; - constexpr char DEFAULT_PREFIX[] = "default:"; - constexpr size_t DEFAULT_PREFIX_LENGTH = sizeof(DEFAULT_PREFIX) - 1; - constexpr char COVERAGE_PREFIX[] = "coverage:"; - constexpr size_t COVERAGE_PREFIX_LENGTH = sizeof(COVERAGE_PREFIX) - 1; - constexpr char PROFILE_FILE_NAME_PREFIX[] = "profile."; - - size_t length_adjust = colon_idx >= 1 ? 0 : 1; - - output_path - .assign_c (androidSystem.get_override_dir (0)) - .append (MONODROID_PATH_SEPARATOR) - .append (PROFILE_FILE_NAME_PREFIX); - - if (value.starts_with (LOG_PREFIX, LOG_PREFIX_LENGTH - length_adjust)) { - output_path.append (MLPD_EXT); - } else if (value.starts_with (AOT_PREFIX, AOT_PREFIX_LENGTH - length_adjust)) { - output_path.append (AOT_EXT); - } else if (value.starts_with (DEFAULT_PREFIX, DEFAULT_PREFIX_LENGTH - length_adjust)) { - output_path.append (MLPD_EXT); - } else if (value.starts_with (COVERAGE_PREFIX, COVERAGE_PREFIX_LENGTH - length_adjust)) { - output_path.append (COV_EXT); - } else { - size_t len = colon_idx < 0 ? value.length () : static_cast(colon_idx + 1); - output_path.append (value.get (), len); - } - - if (colon_idx < 0) - value.append (":"); - else - value.append (","); - value - .append (OUTPUT_ARG) - .append (output_path.get (), output_path.length ()); - } - - /* - * libmono-profiler-log.so profiler won't overwrite existing files. - * Remove it For Great Justice^H^H^H to preserve my sanity! - */ - unlink (output_path.get ()); - - log_warn (LOG_DEFAULT, "Initializing profiler with options: %s", value.get ()); - debug.monodroid_profiler_load (androidSystem.get_runtime_libdir (), value.get (), output_path.get ()); -} -#endif // ndef NET - -/* -Disable LLVM signal handlers. - -This happens when RenderScript needs to be compiled. See https://bugzilla.xamarin.com/show_bug.cgi?id=18016 - -This happens only on first run of the app. LLVM is used to compiled the RenderScript scripts. LLVM, been -a nice and smart library installs a ton of signal handlers and don't chain at all, completely breaking us. - -This is a hack to set llvm::DisablePrettyStackTrace to true and avoid this source of signal handlers. - -As of Android 5.0 (API 21) the symbol no longer exists in libLLVM.so and stack pretty printing is an opt-in -instead of an opt-out feature. LLVM change which removed the symbol is at - -https://github.com/llvm/llvm-project/commit/c10ca903243f97cbc8014f20c64f1318a57a2936 - -*/ -void -MonodroidRuntime::disable_external_signal_handlers (void) -{ -#if !defined (NET) - if (android_api_level >= 21) { - return; - } - - void *llvm = androidSystem.load_dso ("libLLVM.so", JAVA_INTEROP_LIB_LOAD_GLOBALLY, TRUE); - if (llvm) { - bool *disable_signals = reinterpret_cast (java_interop_lib_symbol (llvm, "_ZN4llvm23DisablePrettyStackTraceE", nullptr)); - if (disable_signals) { - *disable_signals = true; - log_info (LOG_DEFAULT, "Disabled LLVM signal trapping"); - } - //MUST NOT dlclose to ensure we don't lose the hack - } -#endif // ndef NET -} - -#if defined (NET) inline void MonodroidRuntime::load_assembly (MonoAssemblyLoadContextGCHandle alc_handle, jstring_wrapper &assembly) { size_t total_time_index; - if (XA_UNLIKELY (FastTiming::enabled ())) { + if (FastTiming::enabled ()) [[unlikely]] { total_time_index = internal_timing->start_event (TimingEventKind::AssemblyLoad); } const char *assm_name = assembly.get_cstr (); - if (XA_UNLIKELY (assm_name == nullptr)) { + if (assm_name == nullptr) [[unlikely]] { log_warn (LOG_ASSEMBLY, "Unable to load assembly into ALC, name is null"); return; } @@ -1822,57 +1305,47 @@ MonodroidRuntime::load_assembly (MonoAssemblyLoadContextGCHandle alc_handle, jst mono_assembly_name_free (aname); - if (XA_UNLIKELY (FastTiming::enabled ())) { + if (FastTiming::enabled ()) [[unlikely]] { internal_timing->end_event (total_time_index, true /* uses_more_info */); - constexpr char PREFIX[] = " (ALC): "; - constexpr size_t PREFIX_SIZE = sizeof(PREFIX) - 1; + constexpr std::string_view PREFIX { " (ALC): " }; - dynamic_local_string more_info { PREFIX }; + dynamic_local_string more_info { PREFIX }; more_info.append_c (assm_name); internal_timing->add_more_info (total_time_index, more_info); } } -#endif // NET inline void MonodroidRuntime::load_assembly (MonoDomain *domain, jstring_wrapper &assembly) { size_t total_time_index; - if (XA_UNLIKELY (FastTiming::enabled ())) { + if (FastTiming::enabled ()) [[unlikely]] { total_time_index = internal_timing->start_event (TimingEventKind::AssemblyLoad); } const char *assm_name = assembly.get_cstr (); - if (XA_UNLIKELY (assm_name == nullptr)) { + if (assm_name == nullptr) [[unlikely]] { log_warn (LOG_ASSEMBLY, "Unable to load assembly into AppDomain, name is null"); return; } MonoAssemblyName *aname = mono_assembly_name_new (assm_name); - -#ifndef ANDROID - if (designerAssemblies.has_assemblies () && designerAssemblies.try_load_assembly (domain, aname) != nullptr) { - log_debug (LOG_ASSEMBLY, "Dynamically opened assembly %s", mono_assembly_name_get_name (aname)); - } else -#endif - { - MonoDomain *current = utils.get_current_domain (); - if (domain != current) { - mono_domain_set (domain, FALSE); - mono_assembly_load_full (aname, NULL, NULL, 0); - mono_domain_set (current, FALSE); - } else { - mono_assembly_load_full (aname, NULL, NULL, 0); - } + MonoDomain *current = utils.get_current_domain (); + if (domain != current) { + mono_domain_set (domain, FALSE); + mono_assembly_load_full (aname, NULL, NULL, 0); + mono_domain_set (current, FALSE); + } else { + mono_assembly_load_full (aname, NULL, NULL, 0); } mono_assembly_name_free (aname); - if (XA_UNLIKELY (FastTiming::enabled ())) { + if (FastTiming::enabled ()) [[unlikely]] { internal_timing->end_event (total_time_index, true /* uses_more_info */); - constexpr char PREFIX[] = " (domain): "; + constexpr std::string_view PREFIX { " (domain): " }; constexpr size_t PREFIX_SIZE = sizeof(PREFIX) - 1; dynamic_local_string more_info { PREFIX }; @@ -1885,7 +1358,7 @@ inline void MonodroidRuntime::load_assemblies (load_assemblies_context_type ctx, bool preload, jstring_array_wrapper &assemblies) { size_t total_time_index; - if (XA_UNLIKELY (FastTiming::enabled ())) { + if (FastTiming::enabled ()) [[unlikely]] { total_time_index = internal_timing->start_event (TimingEventKind::AssemblyPreload); } @@ -1898,7 +1371,7 @@ MonodroidRuntime::load_assemblies (load_assemblies_context_type ctx, bool preloa break; } - if (XA_UNLIKELY (FastTiming::enabled ())) { + if (FastTiming::enabled ()) [[unlikely]] { internal_timing->end_event (total_time_index, true /* uses-more_info */); static_local_string more_info; @@ -1920,10 +1393,8 @@ MonodroidRuntime::create_and_initialize_domain (JNIEnv* env, jclass runtimeClass bool force_preload_assemblies, bool have_split_apks) { MonoDomain* domain = create_domain (env, runtimeApks, is_root_domain, have_split_apks); -#if defined (ANDROID) // Asserting this on desktop apparently breaks a Designer test abort_unless (domain != nullptr, "Failed to create AppDomain"); -#endif // When running on desktop, the root domain is only a dummy so don't initialize it if constexpr (is_running_on_desktop) { @@ -1932,41 +1403,28 @@ MonodroidRuntime::create_and_initialize_domain (JNIEnv* env, jclass runtimeClass } } -#if defined (NET) default_alc = mono_alc_get_default_gchandle (); abort_unless (default_alc != nullptr, "Default AssemblyLoadContext not found"); embeddedAssemblies.install_preload_hooks_for_alc (); log_debug (LOG_ASSEMBLY, "ALC hooks installed"); -#endif // def NET -#ifndef ANDROID - if (assembliesBytes != nullptr && domain != nullptr) - designerAssemblies.add_or_update_from_java (domain, env, assemblies, assembliesBytes, assembliesPaths); -#endif bool preload = (androidSystem.is_assembly_preload_enabled () || (is_running_on_desktop && force_preload_assemblies)); -#if defined (NET) load_assemblies (default_alc, preload, assemblies); init_android_runtime (env, runtimeClass, loader); -#else // def NET - load_assemblies (domain, preload, assemblies); - init_android_runtime (domain, env, runtimeClass, loader); -#endif // ndef NET osBridge.add_monodroid_domain (domain); return domain; } -#if defined (NET) void MonodroidRuntime::monodroid_unhandled_exception (MonoObject *java_exception) { mono_unhandled_exception (java_exception); } -#endif // def NET -#if !defined (RELEASE) || !defined (ANDROID) +#if !defined (RELEASE) MonoReflectionType* MonodroidRuntime::typemap_java_to_managed (MonoString *java_type_name) noexcept { @@ -1978,60 +1436,15 @@ MonodroidRuntime::typemap_managed_to_java (MonoReflectionType *type, const uint8 { return embeddedAssemblies.typemap_managed_to_java (type, mvid); } -#endif // !def RELEASE || !def ANDROID - -#if defined (WINDOWS) -const char* -MonodroidRuntime::get_my_location (bool remove_file_name) -{ - HMODULE hm = NULL; - - DWORD handle_flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT; - if (GetModuleHandleExW (handle_flags, (LPCWSTR) &get_xamarin_android_msbuild_path, &hm) == 0) { - int ret = GetLastError (); - log_warn (LOG_DEFAULT, "Unable to get HANDLE to `libmono-android.debug.dll`; GetModuleHandleExW returned %d\n", ret); - return nullptr; - } - - WCHAR path[MAX_PATH * 2]; - if (GetModuleFileNameW (hm, path, sizeof(path)) == 0) { - int ret = GetLastError (); - log_warn (LOG_DEFAULT, "Unable to get filename to `libmono-android.debug.dll`; GetModuleFileNameW returned %d\n", ret); - return nullptr; - } - - if (remove_file_name) - PathRemoveFileSpecW (path); - - return utils.utf16_to_utf8 (path); -} -#elif defined (APPLE_OS_X) -const char* -MonodroidRuntime::get_my_location (bool remove_file_name) -{ - Dl_info info; - if (dladdr (reinterpret_cast(&MonodroidRuntime::get_my_location), &info) == 0) { - log_warn (LOG_DEFAULT, "Could not lookup library containing `MonodroidRuntime::get_my_location()`; dladdr failed: %s", dlerror ()); - return nullptr; - } - - if (remove_file_name) - return utils.strdup_new (dirname (const_cast(info.dli_fname))); - return utils.strdup_new (info.dli_fname); -} -#endif // defined(WINDOWS) +#endif // !def RELEASE -#if defined (ANDROID) force_inline void MonodroidRuntime::setup_mono_tracing (std::unique_ptr const& mono_log_mask, bool have_log_assembly, bool have_log_gc) { - constexpr char MASK_ASM[] = "asm"; - constexpr size_t MASK_ASM_LEN = sizeof(MASK_ASM) - 1; - constexpr char MASK_DLL[] = "dll"; - constexpr size_t MASK_DLL_LEN = sizeof(MASK_DLL) - 1; - constexpr char MASK_GC[] = "gc"; - constexpr size_t MASK_GC_LEN = sizeof(MASK_GC) - 1; - constexpr char COMMA[] = ","; + constexpr std::string_view MASK_ASM { "asm" }; + constexpr std::string_view MASK_DLL { "dll" }; + constexpr std::string_view MASK_GC { "gc" }; + constexpr std::string_view COMMA { "," }; dynamic_local_string log_mask; if (mono_log_mask == nullptr || *mono_log_mask.get () == '\0') { @@ -2066,11 +1479,11 @@ MonodroidRuntime::setup_mono_tracing (std::unique_ptr const& mono_log_ma string_segment token; while (input_log_mask.next_token (',', token)) { - if (need_asm && token.equal (MASK_ASM, MASK_ASM_LEN)) { + if (need_asm && token.equal (MASK_ASM)) { need_asm = false; - } else if (need_dll && token.equal (MASK_DLL, MASK_DLL_LEN)) { + } else if (need_dll && token.equal (MASK_DLL)) { need_dll = false; - } else if (need_gc && token.equal (MASK_GC, MASK_GC_LEN)) { + } else if (need_gc && token.equal (MASK_GC)) { need_gc = false; } @@ -2106,8 +1519,6 @@ MonodroidRuntime::install_logging_handlers () mono_trace_set_printerr_handler (mono_log_standard_streams_handler); } -#endif // def ANDROID - inline void MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, jobjectArray runtimeApksJava, jstring runtimeNativeLibDir, jobjectArray appDirs, jint localDateTimeOffset, @@ -2126,7 +1537,7 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl FastTiming::initialize ((log_timing_categories & LOG_TIMING_FAST_BARE) == 0); size_t total_time_index; - if (XA_UNLIKELY (FastTiming::enabled ())) { + if (FastTiming::enabled ()) [[unlikely]] { timing = new Timing (); total_time_index = internal_timing->start_event (TimingEventKind::TotalRuntimeInit); } @@ -2134,7 +1545,6 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl jstring_array_wrapper applicationDirs (env, appDirs); jstring_wrapper &home = applicationDirs[SharedConstants::APP_DIRS_FILES_DIR_INDEX]; -#if defined (NET) mono_opt_aot_lazy_assembly_load = application_config.aot_lazy_load ? TRUE : FALSE; { @@ -2152,7 +1562,6 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl const_cast(monovm_props.property_values ()) ); } -#endif // def NET android_api_level = apiLevel; androidSystem.detect_embedded_dso_mode (applicationDirs); @@ -2172,8 +1581,6 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl create_xdg_directories_and_environment (home); androidSystem.set_primary_override_dir (home); - disable_external_signal_handlers (); - jstring_array_wrapper runtimeApks (env, runtimeApksJava); androidSystem.setup_app_library_directories (runtimeApks, applicationDirs, haveSplitApks); @@ -2185,7 +1592,6 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl set_debug_env_vars (); #endif -#if defined (ANDROID) bool have_log_assembly = (log_categories & LOG_ASSEMBLY) != 0; bool have_log_gc = (log_categories & LOG_GC) != 0; @@ -2196,11 +1602,7 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl } setup_mono_tracing (mono_log_mask, have_log_assembly, have_log_gc); - -#if defined (NET) install_logging_handlers (); -#endif // def NET -#endif if (runtimeNativeLibDir != nullptr) { jstr = runtimeNativeLibDir; @@ -2209,83 +1611,26 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl } androidSystem.setup_process_args (runtimeApks); -#if !defined (NET) - // JIT stats based on perf counters are disabled in dotnet/mono - if (XA_UNLIKELY (FastTiming::enabled () && !FastTiming::is_bare_mode ())) { - mono_counters_enable (static_cast(XA_LOG_COUNTERS)); - - dynamic_local_string counters_path; - utils.path_combine (counters_path, androidSystem.get_override_dir (0), "counters.txt"); - log_info_nocheck (LOG_TIMING, "counters path: %s", counters_path.get ()); - counters = utils.monodroid_fopen (counters_path.get (), "a"); - utils.set_world_accessable (counters_path.get ()); - } - - void *dso_handle = nullptr; -#if defined (WINDOWS) || defined (APPLE_OS_X) - const char *my_location = get_my_location (); - if (my_location != nullptr) { - std::unique_ptr dso_path {utils.path_combine (my_location, API_DSO_NAME)}; - log_info (LOG_DEFAULT, "Attempting to load %s", dso_path.get ()); - dso_handle = java_interop_lib_load (dso_path.get (), JAVA_INTEROP_LIB_LOAD_GLOBALLY, nullptr); -#if defined (APPLE_OS_X) - delete[] my_location; -#else // !defined(APPLE_OS_X) - free (static_cast(const_cast(my_location))); // JI allocates with `calloc` -#endif // defined(APPLE_OS_X) - } - - if (dso_handle == nullptr) { - log_info (LOG_DEFAULT, "Attempting to load %s with \"bare\" dlopen", API_DSO_NAME); - dso_handle = java_interop_lib_load (API_DSO_NAME, JAVA_INTEROP_LIB_LOAD_GLOBALLY, nullptr); - } -#endif // defined(WINDOWS) || defined(APPLE_OS_X) - if (dso_handle == nullptr) - dso_handle = androidSystem.load_dso_from_any_directories (API_DSO_NAME, JAVA_INTEROP_LIB_LOAD_GLOBALLY); - - init_internal_api_dso (dso_handle); -#endif // ndef NET mono_dl_fallback_register (monodroid_dlopen, monodroid_dlsym, nullptr, nullptr); set_profile_options (); set_trace_options (); -#if defined (DEBUG) && !defined (WINDOWS) +#if defined (DEBUG) debug.start_debugging_and_profiling (); #endif -#if !defined (NET) - mono_config_parse_memory (reinterpret_cast (monodroid_config)); - mono_register_machine_config (reinterpret_cast (monodroid_machine_config)); -#endif // ndef NET log_debug (LOG_DEFAULT, "Probing for Mono AOT mode\n"); MonoAotMode mode = MonoAotMode::MONO_AOT_MODE_NONE; if (androidSystem.is_mono_aot_enabled ()) { mode = androidSystem.get_mono_aot_mode (); -#if !defined (NET) - if (mode == MonoAotMode::MONO_AOT_MODE_LAST) { - // Hack. See comments in android-system.hh - if (!androidSystem.is_interpreter_enabled ()) { - mode = MonoAotMode::MONO_AOT_MODE_NONE; - } - } - - if (mode != MonoAotMode::MONO_AOT_MODE_NONE) { - if (mode != MonoAotMode::MONO_AOT_MODE_LAST) { - log_info (LOG_DEFAULT, "Enabling AOT mode in Mono"); - } else { - log_info (LOG_DEFAULT, "Enabling Mono Interpreter"); - } - } -#else // defined (NET) if (mode != MonoAotMode::MONO_AOT_MODE_INTERP_ONLY) { log_debug (LOG_DEFAULT, "Enabling AOT mode in Mono"); } else { log_debug (LOG_DEFAULT, "Enabling Mono Interpreter"); } -#endif // !defined (NET) } mono_jit_set_aot_mode (mode); @@ -2302,18 +1647,14 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl dynamic_local_string runtime_args; androidSystem.monodroid_get_system_property (Debug::DEBUG_MONO_EXTRA_PROPERTY, runtime_args); -#if TRACE - __android_log_print (ANDROID_LOG_INFO, "*jonp*", "debug.mono.extra=%s", runtime_args); -#endif - size_t mono_runtime_init_index; - if (XA_UNLIKELY (FastTiming::enabled ())) { + if (FastTiming::enabled ()) [[unlikely]] { mono_runtime_init_index = internal_timing->start_event (TimingEventKind::MonoRuntimeInit); } mono_runtime_init (env, runtime_args); - if (XA_UNLIKELY (FastTiming::enabled ())) { + if (FastTiming::enabled ()) [[unlikely]] { internal_timing->end_event (mono_runtime_init_index); } @@ -2322,39 +1663,31 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl /* the first assembly is used to initialize the AppDomain name */ create_and_initialize_domain (env, klass, runtimeApks, assemblies, nullptr, assembliesPaths, loader, /*is_root_domain:*/ true, /*force_preload_assemblies:*/ false, haveSplitApks); -#if defined (ANDROID) && !defined (NET) - // Mono from mono/mono has a bug which requires us to install the handlers after `mono_init_jit_version` is called - install_logging_handlers (); -#endif // def ANDROID && ndef NET - // Install our dummy exception handler on Desktop if constexpr (is_running_on_desktop) { mono_add_internal_call ("System.Diagnostics.Debugger::Mono_UnhandledException_internal(System.Exception)", reinterpret_cast (monodroid_Mono_UnhandledException_internal)); } - if (XA_UNLIKELY (utils.should_log (LOG_DEFAULT))) { + if (utils.should_log (LOG_DEFAULT)) [[unlikely]] { log_info_nocheck ( LOG_DEFAULT, ".NET Android version: %s (%s; %s); built on %s; NDK version: %s; API level: %s; MonoVM version: %s", - BuildInfo::xa_version, - BuildInfo::architecture, - BuildInfo::kind, - BuildInfo::date, - BuildInfo::ndk_version, - BuildInfo::ndk_api_level, + BuildInfo::xa_version.data (), + BuildInfo::architecture.data (), + BuildInfo::kind.data (), + BuildInfo::date.data (), + BuildInfo::ndk_version.data (), + BuildInfo::ndk_api_level.data (), mono_get_runtime_build_info () ); } - if (XA_UNLIKELY (FastTiming::enabled ())) { + if (FastTiming::enabled ()) [[unlikely]] { internal_timing->end_event (total_time_index); -#if !defined (NET) - dump_counters ("## Runtime.init: end"); -#endif // ndef NET } -#if defined (RELEASE) && defined (ANDROID) && defined (NET) +#if defined (RELEASE) if (application_config.marshal_methods_enabled) { xamarin_app_init (env, get_function_pointer_at_runtime); } @@ -2362,33 +1695,6 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl startup_in_progress = false; } -#if !defined (NET) -void -MonodroidRuntime::dump_counters (const char *format, ...) -{ - if (counters == nullptr) - return; - - va_list args; - va_start (args, format); - dump_counters_v (format, args); - va_end (args); -} - -void -MonodroidRuntime::dump_counters_v (const char *format, va_list args) -{ - if (counters == nullptr) - return; - - fprintf (counters, "\n"); - vfprintf (counters, format, args); - fprintf (counters, "\n"); - - mono_counters_dump (MonodroidRuntime::XA_LOG_COUNTERS, counters); -} -#endif // ndef NET - JNIEXPORT jint JNICALL JNI_OnLoad (JavaVM *vm, void *reserved) { @@ -2445,7 +1751,7 @@ MonodroidRuntime::Java_mono_android_Runtime_register (JNIEnv *env, jstring manag { size_t total_time_index; - if (XA_UNLIKELY (FastTiming::enabled ())) { + if (FastTiming::enabled ()) [[unlikely]] { total_time_index = internal_timing->start_event (TimingEventKind::RuntimeRegister); } @@ -2454,43 +1760,13 @@ MonodroidRuntime::Java_mono_android_Runtime_register (JNIEnv *env, jstring manag int methods_len = env->GetStringLength (methods); const jchar *methods_ptr = env->GetStringChars (methods, nullptr); -#if !defined (NET) || !defined (ANDROID) - void *args[] = { - &managedType_ptr, - &managedType_len, - &nativeClass, - &methods_ptr, - &methods_len, - }; - MonoMethod *register_jni_natives = registerType; -#endif // ndef NET || ndef ANDROID - -#if !defined (NET) - MonoDomain *domain = utils.get_current_domain (/* attach_thread_if_needed */ false); - mono_jit_thread_attach (domain); - // Refresh current domain as it might have been modified by the above call - domain = mono_domain_get (); - - if constexpr (is_running_on_desktop) { - MonoClass *runtime = utils.monodroid_get_class_from_name (domain, SharedConstants::MONO_ANDROID_ASSEMBLY_NAME, SharedConstants::ANDROID_RUNTIME_NS_NAME, SharedConstants::JNIENVINIT_CLASS_NAME); - register_jni_natives = mono_class_get_method_from_name (runtime, "RegisterJniNatives", 5); - } - - utils.monodroid_runtime_invoke (domain, register_jni_natives, nullptr, args, nullptr); -#else // ndef NET mono_jit_thread_attach (nullptr); // There's just one domain in .net - -#if !defined (ANDROID) - mono_runtime_invoke (register_jni_natives, nullptr, args, nullptr); -#else jnienv_register_jni_natives (managedType_ptr, managedType_len, nativeClass, methods_ptr, methods_len); -#endif // ndef ANDROID -#endif // def NET env->ReleaseStringChars (methods, methods_ptr); env->ReleaseStringChars (managedType, managedType_ptr); - if (XA_UNLIKELY (FastTiming::enabled ())) { + if (FastTiming::enabled ()) [[unlikely]] { internal_timing->end_event (total_time_index, true /* uses_more_info */); dynamic_local_string type; @@ -2499,9 +1775,6 @@ MonodroidRuntime::Java_mono_android_Runtime_register (JNIEnv *env, jstring manag env->ReleaseStringUTFChars (managedType, mt_ptr); internal_timing->add_more_info (total_time_index, type); -#if !defined (NET) - dump_counters ("## Runtime.register: type=%s\n", type.get ()); -#endif } } @@ -2563,10 +1836,5 @@ get_jnienv (void) JNIEXPORT void JNICALL Java_mono_android_Runtime_propagateUncaughtException (JNIEnv *env, [[maybe_unused]] jclass klass, jobject javaThread, jthrowable javaException) { -#if defined (NET) monodroidRuntime.propagate_uncaught_exception (env, javaThread, javaException); -#else // def NET - MonoDomain *domain = utils.get_current_domain (); - monodroidRuntime.propagate_uncaught_exception (domain, env, javaThread, javaException); -#endif // ndef NET } diff --git a/src/monodroid/jni/monovm-properties.cc b/src/monodroid/jni/monovm-properties.cc index b98eac0b6ee..8ec3d88f852 100644 --- a/src/monodroid/jni/monovm-properties.cc +++ b/src/monodroid/jni/monovm-properties.cc @@ -9,7 +9,7 @@ MonoVMProperties::property_array MonoVMProperties::_property_keys { }; MonoVMProperties::property_array MonoVMProperties::_property_values { - SharedConstants::runtime_identifier, + SharedConstants::runtime_identifier.data (), nullptr, nullptr, }; diff --git a/src/monodroid/jni/osbridge.cc b/src/monodroid/jni/osbridge.cc index f7ca9467243..dc8d50db6d3 100644 --- a/src/monodroid/jni/osbridge.cc +++ b/src/monodroid/jni/osbridge.cc @@ -1,9 +1,7 @@ #include #include -#if defined (__linux__) || defined (__linux) #include -#endif #if defined (HAVE_GETTID_IN_UNISTD_H) #if !defined __USE_GNU @@ -17,15 +15,6 @@ #include #include -#if defined (WINDOWS) -#include -#include -#include -#include -#include -#include -#endif - #include "globals.hh" #include "osbridge.hh" @@ -85,26 +74,7 @@ gc_cross_references_cb (int num_sccs, MonoGCBridgeSCC **sccs, int num_xrefs, Mon osBridge.gc_cross_references (num_sccs, sccs, num_xrefs, xrefs); } -#ifdef WINDOWS -using tid_type = int; -#else using tid_type = pid_t; -#endif -// glibc does *not* have a wrapper for the gettid syscall, Android NDK has it -#if !defined (ANDROID) && !defined (HAVE_GETTID_IN_UNISTD_H) -static tid_type gettid () -{ -#ifdef WINDOWS - return GetCurrentThreadId (); -#elif defined (__linux__) || defined (__linux) - return static_cast(syscall (SYS_gettid)); -#else - uint64_t tid; - pthread_threadid_np (nullptr, &tid); - return static_cast(tid); -#endif -} -#endif // ANDROID // Do this instead of using memset so that individual pointers are set atomically void @@ -783,8 +753,14 @@ OSBridge::AddReferenceTarget OSBridge::target_from_scc (MonoGCBridgeSCC **sccs, int idx, JNIEnv *env, jobject temporary_peers) { MonoGCBridgeSCC *scc = sccs [idx]; - if (scc->num_objs > 0) + if (scc->num_objs > 0) { + // Disable array bounds checking here. The compiler cannot determine that the above `if` expression protects + // the code from out of bounds access to array elements. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warray-bounds" return target_from_mono_object (scc->objs [0]); +#pragma clang diagnostic pop + } jobject jobj = env->CallObjectMethod (temporary_peers, ArrayList_get, scc_get_stashed_index (scc)); return target_from_jobject (jobj); @@ -826,7 +802,12 @@ OSBridge::gc_prepare_for_java_collection (JNIEnv *env, int num_sccs, MonoGCBridg * Solution: Make all objects within the SCC directly or indirectly reference each other */ if (scc->num_objs > 1) { + // Disable array bounds checking here. The compiler cannot determine that the above `if` expression protects + // the code from out of bounds access to array elements. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warray-bounds" MonoObject *first = scc->objs [0]; +#pragma clang diagnostic pop MonoObject *prev = first; /* start at the second item, ref j from j-1 */ @@ -1142,13 +1123,9 @@ OSBridge::add_monodroid_domain (MonoDomain *domain) */ MonoClass *runtime = utils.monodroid_get_class_from_name ( domain, -#if defined (NET) - SharedConstants::MONO_ANDROID_RUNTIME_ASSEMBLY_NAME, -#else - SharedConstants::MONO_ANDROID_ASSEMBLY_NAME, -#endif - SharedConstants::ANDROID_RUNTIME_NS_NAME, - SharedConstants::ANDROID_RUNTIME_INTERNAL_CLASS_NAME + SharedConstants::MONO_ANDROID_RUNTIME_ASSEMBLY_NAME.data (), + SharedConstants::ANDROID_RUNTIME_NS_NAME.data (), + SharedConstants::ANDROID_RUNTIME_INTERNAL_CLASS_NAME.data () ); node->domain = domain; @@ -1158,45 +1135,3 @@ OSBridge::add_monodroid_domain (MonoDomain *domain) domains_list = node; } - -#if !defined (NET) && !defined (ANDROID) -void -OSBridge::remove_monodroid_domain (MonoDomain *domain) -{ - MonodroidBridgeProcessingInfo *node = domains_list; - MonodroidBridgeProcessingInfo *prev = nullptr; - - while (node != nullptr) { - if (node->domain != domain) { - prev = node; - node = node->next; - continue; - } - - if (prev != nullptr) - prev->next = node->next; - else - domains_list = node->next; - - free (node); - - break; - } -} - -void -OSBridge::on_destroy_contexts () -{ - /* If domains_list is now empty, we are about to unload Monodroid.dll. - * Clear the global bridge info structure since it's pointing into soon-invalid memory. - * FIXME: It is possible for a thread to get into `gc_bridge_class_kind` after this clear - * occurs, but before the stop-the-world during mono_domain_unload. If this happens, - * it can falsely mark a class as transparent. This is considered acceptable because - * this case is *very* rare and the worst case scenario is a resource leak. - * The real solution would be to add a new callback, called while the world is stopped - * during `mono_gc_clear_domain`, and clear the bridge info during that. - */ - if (!domains_list) - osBridge.clear_mono_java_gc_bridge_info (); -} -#endif // ndef NET && ndef ANDROID diff --git a/src/monodroid/jni/osbridge.hh b/src/monodroid/jni/osbridge.hh index ae6e0ff9478..217470e92c8 100644 --- a/src/monodroid/jni/osbridge.hh +++ b/src/monodroid/jni/osbridge.hh @@ -3,6 +3,7 @@ #define __OS_BRIDGE_H #include +#include #include namespace xamarin::android::internal @@ -122,9 +123,6 @@ namespace xamarin::android::internal void initialize_on_onload (JavaVM *vm, JNIEnv *env); void initialize_on_runtime_init (JNIEnv *env, jclass runtimeClass); void add_monodroid_domain (MonoDomain *domain); -#if !defined (NET) - void remove_monodroid_domain (MonoDomain *domain); -#endif // ndef NET void on_destroy_contexts (); private: diff --git a/src/monodroid/jni/pinvoke-override-api.cc b/src/monodroid/jni/pinvoke-override-api.cc index fe4bc69c3a6..94232f60045 100644 --- a/src/monodroid/jni/pinvoke-override-api.cc +++ b/src/monodroid/jni/pinvoke-override-api.cc @@ -496,7 +496,7 @@ MonodroidRuntime::handle_other_pinvoke_request (const char *library_name, hash_t handle = fetch_or_create_pinvoke_map_entry (lib_name, entry_name, entrypoint_name_hash, lib_map, /* need_lock */ false); } else { - if (XA_UNLIKELY (iter->second == nullptr)) { + if (iter->second == nullptr) [[unlikely]] { log_warn (LOG_ASSEMBLY, "Internal error: null entry in p/invoke map for key '%s'", library_name); return nullptr; // fall back to `monodroid_dlopen` } @@ -520,7 +520,7 @@ MonodroidRuntime::monodroid_pinvoke_override (const char *library_name, const ch if (library_name_hash == java_interop_library_hash || library_name_hash == xa_internal_api_library_hash) { PinvokeEntry *entry = find_pinvoke_address (entrypoint_hash, internal_pinvokes, internal_pinvokes_count); - if (XA_UNLIKELY (entry == nullptr)) { + if (entry == nullptr) [[unlikely]] { log_fatal (LOG_ASSEMBLY, "Internal p/invoke symbol '%s @ %s' (hash: 0x%zx) not found in compile-time map.", library_name, entrypoint_name, entrypoint_hash); log_fatal (LOG_ASSEMBLY, "compile-time map contents:"); for (size_t i = 0; i < internal_pinvokes_count; i++) { diff --git a/src/monodroid/jni/platform-compat.hh b/src/monodroid/jni/platform-compat.hh index 62502bbcafa..89992af8e0b 100644 --- a/src/monodroid/jni/platform-compat.hh +++ b/src/monodroid/jni/platform-compat.hh @@ -1,63 +1,11 @@ #ifndef __PLATFORM_COMPAT_HH #define __PLATFORM_COMPAT_HH -#include +#include -#if WINDOWS -constexpr char MONODROID_PATH_SEPARATOR[] = "\\"; -constexpr char MONODROID_PATH_SEPARATOR_CHAR = '\\'; -#else // !WINDOWS -constexpr char MONODROID_PATH_SEPARATOR[] = "/"; -constexpr char MONODROID_PATH_SEPARATOR_CHAR = '/'; -#endif // WINDOWS -constexpr size_t MONODROID_PATH_SEPARATOR_LENGTH = sizeof(MONODROID_PATH_SEPARATOR) - 1; - -#if WINDOWS -typedef struct _stat monodroid_stat_t; -#define monodroid_dir_t _WDIR -typedef struct _wdirent monodroid_dirent_t; -#else // !WINDOWS -typedef struct stat monodroid_stat_t; -#define monodroid_dir_t DIR -typedef struct dirent monodroid_dirent_t; -#endif // WINDOWS - -#define DEFAULT_DIRECTORY_MODE S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH - -#if defined (_MSC_VER) -#define inline __inline -#define force_inline __forceinline -#elif defined (__GNUC__) -#ifndef XA_LIKELY -#define XA_LIKELY(expr) (__builtin_expect ((expr) != 0, 1)) -#endif - -#ifndef XA_UNLIKELY -#define XA_UNLIKELY(expr) (__builtin_expect ((expr) != 0, 0)) -#endif +static inline constexpr int DEFAULT_DIRECTORY_MODE = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; #define force_inline inline __attribute__((always_inline)) #define never_inline __attribute__((noinline)) -#endif // _MSV_VER - -#ifndef force_inline -#define force_inline inline -#endif - -#ifndef never_inline -#define never_inline -#endif - -#ifndef inline -#define inline inline -#endif - -#ifndef XA_LIKELY -#define XA_LIKELY(expr) (expr) -#endif - -#ifndef XA_UNLIKELY -#define XA_UNLIKELY(expr) (expr) -#endif #endif // __PLATFORM_COMPAT_HH diff --git a/src/monodroid/jni/shared-constants.hh b/src/monodroid/jni/shared-constants.hh index a88dbcdf569..10e0c38ec00 100644 --- a/src/monodroid/jni/shared-constants.hh +++ b/src/monodroid/jni/shared-constants.hh @@ -1,14 +1,15 @@ #ifndef __SHARED_CONSTANTS_HH #define __SHARED_CONSTANTS_HH +#include #include "cpp-util.hh" namespace xamarin::android::internal { // _WIN32 is defined with _WIN64 so _WIN64 must be checked first. -#if __SIZEOF_POINTER__ == 8 || defined (_WIN64) +#if __SIZEOF_POINTER__ == 8 #define __BITNESS__ "64bit" -#elif __SIZEOF_POINTER__ == 4 || defined (_WIN32) +#elif __SIZEOF_POINTER__ == 4 #define __BITNESS__ "32bit" #else #error Unknown pointer size for this platform @@ -17,53 +18,43 @@ namespace xamarin::android::internal class SharedConstants { public: -#if defined (NET) - static constexpr char MONO_ANDROID_RUNTIME_ASSEMBLY_NAME[] = "Mono.Android.Runtime"; -#endif - static constexpr char MONO_ANDROID_ASSEMBLY_NAME[] = "Mono.Android"; - static constexpr char JAVA_INTEROP_ASSEMBLY_NAME[] = "Java.Interop"; - - static constexpr char ANDROID_RUNTIME_NS_NAME[] = "Android.Runtime"; - static constexpr char JNIENVINIT_CLASS_NAME[] = "JNIEnvInit"; - static constexpr char JNIENV_CLASS_NAME[] = "JNIEnv"; - static constexpr char ANDROID_ENVIRONMENT_CLASS_NAME[] = "AndroidEnvironment"; - static constexpr char ANDROID_RUNTIME_INTERNAL_CLASS_NAME[] = "AndroidRuntimeInternal"; - - static constexpr char DLL_EXTENSION[] = ".dll"; - -#if defined (NET) - static constexpr char RUNTIME_CONFIG_BLOB_NAME[] = "rc.bin"; -#endif // def NET - -#if defined (ANDROID) || defined (__linux__) || defined (__linux) - static constexpr char MONO_SGEN_SO[] = "libmonosgen-2.0.so"; - static constexpr char MONO_SGEN_ARCH_SO[] = "libmonosgen-" __BITNESS__ "-2.0.so"; -#elif APPLE_OS_X - static constexpr char MONO_SGEN_SO[] = "libmonosgen-2.0.dylib"; - static constexpr char MONO_SGEN_ARCH_SO[] = "libmonosgen-" __BITNESS__ "-2.0.dylib"; -#elif WINDOWS - static constexpr char MONO_SGEN_SO[] = "libmonosgen-2.0.dll"; - static constexpr char MONO_SGEN_ARCH_SO[] = "libmonosgen-" __BITNESS__ "-2.0.dll"; -#else - static constexpr char MONO_SGEN_SO[] = "monosgen-2.0"; - static constexpr char MONO_SGEN_ARCH_SO[] = "monosgen-" __BITNESS__ "-2.0"; -#endif + static constexpr std::string_view MONO_ANDROID_RUNTIME_ASSEMBLY_NAME { "Mono.Android.Runtime" }; + static constexpr std::string_view MONO_ANDROID_ASSEMBLY_NAME { "Mono.Android" }; + static constexpr std::string_view JAVA_INTEROP_ASSEMBLY_NAME { "Java.Interop" }; + static constexpr std::string_view ANDROID_RUNTIME_NS_NAME { "Android.Runtime" }; + static constexpr std::string_view JNIENVINIT_CLASS_NAME { "JNIEnvInit" }; + static constexpr std::string_view JNIENV_CLASS_NAME { "JNIEnv" }; + static constexpr std::string_view ANDROID_ENVIRONMENT_CLASS_NAME { "AndroidEnvironment" }; + static constexpr std::string_view ANDROID_RUNTIME_INTERNAL_CLASS_NAME { "AndroidRuntimeInternal" }; + static constexpr std::string_view DLL_EXTENSION { ".dll" }; + static constexpr std::string_view RUNTIME_CONFIG_BLOB_NAME { "rc.bin" }; + 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__" }; #if __arm__ - static constexpr char android_abi[] = "armeabi_v7a"; - static constexpr char runtime_identifier[] = "android-arm"; + static constexpr std::string_view android_abi { "armeabi_v7a" }; + static constexpr std::string_view android_lib_abi { "armeabi-v7a" }; + static constexpr std::string_view runtime_identifier { "android-arm" }; #elif __aarch64__ - static constexpr char android_abi[] = "arm64_v8a"; - static constexpr char runtime_identifier[] = "android-arm64"; + static constexpr std::string_view android_abi { "arm64_v8a" }; + static constexpr std::string_view android_lib_abi { "arm64-v8a" }; + static constexpr std::string_view runtime_identifier { "android-arm64" }; #elif __x86_64__ - static constexpr char android_abi[] = "x86_64"; - static constexpr char runtime_identifier[] = "android-x64"; + static constexpr std::string_view android_abi { "x86_64" }; + static constexpr std::string_view android_lib_abi { "x86_64" }; + static constexpr std::string_view runtime_identifier { "android-x64" }; #elif __i386__ - static constexpr char android_abi[] = "x86"; - static constexpr char runtime_identifier[] = "android-x86"; + static constexpr std::string_view android_abi { "x86" }; + static constexpr std::string_view android_lib_abi { "x86" }; + static constexpr std::string_view runtime_identifier { "android-x86" }; #endif - static constexpr auto split_config_abi_apk_name = concat_const ("/split_config.", android_abi, ".apk"); + static constexpr std::string_view split_config_prefix { "/split_config." }; + static constexpr std::string_view split_config_extension { ".apk" }; + + static constexpr size_t split_config_abi_apk_name_size = calc_size (split_config_prefix, android_abi, split_config_extension); + static constexpr auto split_config_abi_apk_name = concat_string_views (split_config_prefix, android_abi, split_config_extension); // // Indexes must match these of trhe `appDirs` array in src/java-runtime/mono/android/MonoPackageManager.java diff --git a/src/monodroid/jni/strings.hh b/src/monodroid/jni/strings.hh index bf41b519b44..97f22e0b805 100644 --- a/src/monodroid/jni/strings.hh +++ b/src/monodroid/jni/strings.hh @@ -5,11 +5,11 @@ #include #include #include +#include #include #include #include "platform-compat.hh" -#include "logger.hh" #include "helpers.hh" #include "shared-constants.hh" @@ -81,6 +81,11 @@ namespace xamarin::android::internal return equal (s, Size - 1); } + force_inline bool equal (std::string_view const& s) noexcept + { + return equal (s.data (), s.length ()); + } + force_inline bool starts_with_c (const char *s) const noexcept { if (s == nullptr) @@ -108,6 +113,11 @@ namespace xamarin::android::internal return starts_with (s, Size - 1); } + force_inline bool starts_with (std::string_view const& s) const noexcept + { + return starts_with (s.data (), s.length ()); + } + force_inline bool has_at (const char ch, size_t index) const noexcept { if (!can_access (index)) { @@ -191,7 +201,7 @@ namespace xamarin::android::internal private: force_inline bool can_access (size_t index) const noexcept { - if (XA_UNLIKELY (!initialized () || start () == nullptr)) { + if (!initialized () || start () == nullptr) [[unlikely]] { return false; } @@ -450,6 +460,11 @@ namespace xamarin::android::internal return append (str.get (), str.length ()); } + force_inline string_base& append (std::string_view const& sv) noexcept + { + return append (sv.data (), sv.length ()); + } + template force_inline string_base& append (const char (&s)[Size]) noexcept { @@ -520,6 +535,11 @@ namespace xamarin::android::internal return assign (s, strlen (s)); } + force_inline string_base& assign (std::string_view const& sv) noexcept + { + return assign (sv.data (), sv.size ()); + } + template force_inline string_base& assign (const char (&s)[Size]) noexcept { @@ -622,6 +642,11 @@ namespace xamarin::android::internal return starts_with (s, Size - 1); } + force_inline bool starts_with (std::string_view const& s) noexcept + { + return starts_with (s.data (), s.length ()); + } + force_inline void set_length_after_direct_write (size_t new_length) noexcept { set_length (new_length); @@ -737,7 +762,7 @@ namespace xamarin::android::internal force_inline void ensure_valid_index (size_t access_index) const noexcept { - if (XA_LIKELY (access_index < idx && access_index < buffer.size ())) { + if (access_index < idx && access_index < buffer.size ()) [[likely]] { return; } @@ -822,6 +847,12 @@ namespace xamarin::android::internal { base::append (str); } + + explicit dynamic_local_string (std::string_view const& str) + : base (str.length ()) + { + base::append (str); + } }; } #endif // __STRINGS_HH diff --git a/src/monodroid/jni/timezones.cc b/src/monodroid/jni/timezones.cc index 4e8a31df37f..f5179350ed9 100644 --- a/src/monodroid/jni/timezones.cc +++ b/src/monodroid/jni/timezones.cc @@ -33,9 +33,9 @@ init () if (AndroidEnvironment_NotifyTimeZoneChanged) return; - Mono_Android_dll = utils.monodroid_load_assembly (utils.get_current_domain (), SharedConstants::MONO_ANDROID_ASSEMBLY_NAME); + Mono_Android_dll = utils.monodroid_load_assembly (utils.get_current_domain (), SharedConstants::MONO_ANDROID_ASSEMBLY_NAME.data ()); Mono_Android_image = mono_assembly_get_image (Mono_Android_dll); - AndroidEnvironment = mono_class_from_name (Mono_Android_image, SharedConstants::ANDROID_RUNTIME_NS_NAME, SharedConstants::ANDROID_ENVIRONMENT_CLASS_NAME); + AndroidEnvironment = mono_class_from_name (Mono_Android_image, SharedConstants::ANDROID_RUNTIME_NS_NAME.data (), SharedConstants::ANDROID_ENVIRONMENT_CLASS_NAME.data ()); AndroidEnvironment_NotifyTimeZoneChanged = mono_class_get_method_from_name (AndroidEnvironment, "NotifyTimeZoneChanged", 0); if (AndroidEnvironment_NotifyTimeZoneChanged == nullptr) { diff --git a/src/monodroid/jni/timing-internal.hh b/src/monodroid/jni/timing-internal.hh index d323e1e98f6..47417123f27 100644 --- a/src/monodroid/jni/timing-internal.hh +++ b/src/monodroid/jni/timing-internal.hh @@ -2,44 +2,20 @@ #define __TIMING_INTERNAL_HH #include -#include -#include +#include #include -#include -#include #include -#include "cpp-util.hh" #include "logger.hh" #include "startup-aware-lock.hh" #include "strings.hh" #include "util.hh" #include "shared-constants.hh" -#undef HAVE_CONCEPTS - -// Xcode has supports for concepts only since 12.5, however -// even in 13.2 support for them appears buggy. Disable for -// now -#if __has_include () && !defined(__APPLE__) -#define HAVE_CONCEPTS -#include -#endif // __has_include && ndef __APPLE__ - namespace xamarin::android::internal { -#if defined (ANDROID) || defined (__linux__) || defined (__linux) - using timestruct = timespec; -#else - using timestruct = timeval; -#endif - -#if defined (ANDROID) // bionic should use `time_t` in the timespec struct, but it uses `long` instead using time_type = long; -#else - using time_type = time_t; -#endif // Events should never change their assigned values and no values should be reused. // Values are used by the test runner to determine what measurement was taken. @@ -85,7 +61,6 @@ namespace xamarin::android::internal const char* more_info; }; -#if defined (HAVE_CONCEPTS) template concept TimingPointType = requires (T a) { { a.sec } -> std::same_as; @@ -98,7 +73,6 @@ namespace xamarin::android::internal { a.ms } -> std::same_as; { a.ns } -> std::same_as; }; -#endif class FastTiming final { @@ -132,7 +106,7 @@ namespace xamarin::android::internal force_inline static void initialize (bool log_immediately) noexcept { - if (XA_LIKELY (!utils.should_log (LOG_TIMING))) { + if (!utils.should_log (LOG_TIMING)) [[likely]] { return; } @@ -161,7 +135,7 @@ namespace xamarin::android::internal { size_t index = next_event_index.fetch_add (1); - if (XA_UNLIKELY (index >= events.capacity ())) { + if (index >= events.capacity ()) [[unlikely]] { StartupAwareLock lock (event_vector_realloc_mutex); if (index >= events.size ()) { // don't increase unnecessarily, if another thread has already done that // Double the vector size. We should, in theory, check for integer overflow here, but it's more @@ -183,7 +157,7 @@ namespace xamarin::android::internal force_inline void end_event (size_t event_index, bool uses_more_info = false) noexcept { - if (XA_UNLIKELY (!is_valid_event_index (event_index, __PRETTY_FUNCTION__))) { + if (!is_valid_event_index (event_index, __PRETTY_FUNCTION__)) [[unlikely]] { return; } @@ -194,7 +168,7 @@ namespace xamarin::android::internal template force_inline void add_more_info (size_t event_index, string_base const& str) noexcept { - if (XA_UNLIKELY (!is_valid_event_index (event_index, __PRETTY_FUNCTION__))) { + if (!is_valid_event_index (event_index, __PRETTY_FUNCTION__)) [[unlikely]] { return; } @@ -204,7 +178,7 @@ namespace xamarin::android::internal force_inline void add_more_info (size_t event_index, const char* str) noexcept { - if (XA_UNLIKELY (!is_valid_event_index (event_index, __PRETTY_FUNCTION__))) { + if (!is_valid_event_index (event_index, __PRETTY_FUNCTION__)) [[unlikely]] { return; } @@ -215,23 +189,14 @@ namespace xamarin::android::internal force_inline static void get_time (time_t &seconds_out, uint64_t& ns_out) noexcept { int ret; - timestruct tv_ctm; + timespec tv_ctm; -#if defined (ANDROID) || defined (__linux__) || defined (__linux) ret = clock_gettime (CLOCK_MONOTONIC, &tv_ctm); ns_out = ret == 0 ? static_cast(tv_ctm.tv_nsec) : 0; -#else - ret = gettimeofday (&tv_ctm, static_cast (nullptr)); - ns_out = ret == 0 ? static_cast(tv_ctm.tv_usec * 1000LL) : 0; -#endif seconds_out = ret == 0 ? tv_ctm.tv_sec : 0; } -#if defined (HAVE_CONCEPTS) template -#else - template -#endif force_inline static void calculate_interval (P const& start, P const& end, I &result) noexcept { uint64_t nsec; @@ -255,11 +220,7 @@ namespace xamarin::android::internal result.ns = static_cast(nsec % ns_in_millisecond); } -#if defined (HAVE_CONCEPTS) template -#else - template -#endif force_inline static void calculate_interval (P const& start, P const& end, I &result, uint64_t& total_ns) noexcept { calculate_interval (start, end, result); @@ -282,7 +243,7 @@ namespace xamarin::android::internal force_inline bool is_valid_event_index (size_t index, const char *method_name) noexcept { - if (XA_UNLIKELY (index >= events.capacity ())) { + if (index >= events.capacity ()) [[unlikely]] { log_warn (LOG_TIMING, "Invalid event index passed to method '%s'", method_name); return false; } diff --git a/src/monodroid/jni/timing.hh b/src/monodroid/jni/timing.hh index 925fb7d84a5..68bf982dd98 100644 --- a/src/monodroid/jni/timing.hh +++ b/src/monodroid/jni/timing.hh @@ -6,9 +6,7 @@ #include #include -#ifdef ANDROID #include -#endif #include "cppcompat.hh" #include "logger.hh" diff --git a/src/monodroid/jni/util.cc b/src/monodroid/jni/util.cc index edc90d222f6..b7bcdd805b5 100644 --- a/src/monodroid/jni/util.cc +++ b/src/monodroid/jni/util.cc @@ -1,35 +1,23 @@ -#include +#include #include #include -#include -#ifndef WINDOWS +#include +#include + #include -#else -#include -#include -#endif #include #include -#include + #ifdef HAVE_BSD_STRING_H #include #endif -#ifdef WINDOWS -#include -#endif - #include #include #include -#include "java-interop-util.h" - -#include "monodroid.h" #include "util.hh" #include "globals.hh" -#include "monodroid-glue.hh" -#include "cpp-util.hh" #include "timing-internal.hh" using namespace xamarin::android; @@ -47,35 +35,16 @@ timing_diff::timing_diff (const timing_period &period) Util::Util () { -#ifndef WINDOWS page_size = getpagesize (); -#else // defined(WINDOWS) - SYSTEM_INFO info; - GetSystemInfo (&info); - page_size = info.dwPageSize; -#endif // defined(WINDOWS) } int Util::send_uninterrupted (int fd, void *buf, size_t len) { ssize_t res; -#ifdef WINDOWS - const char *buffer = static_cast (buf); -#else - void *buffer = buf; -#endif + do { - res = send ( - fd, - buffer, -#ifdef WINDOWS - static_cast(len), -#else - len, -#endif - 0 - ); + res = send (fd, buf, len, 0); } while (res == -1 && errno == EINTR); return static_cast(res) == len; @@ -84,11 +53,8 @@ Util::send_uninterrupted (int fd, void *buf, size_t len) ssize_t Util::recv_uninterrupted (int fd, void *buf, size_t len) { -#if defined (WINDOWS) - using nbytes_type = int; -#else using nbytes_type = size_t; -#endif + ssize_t res; size_t total = 0; int flags = 0; @@ -146,7 +112,6 @@ Util::monodroid_store_package_name (const char *name) log_debug (LOG_DEFAULT, "Generated hash 0x%s for package name %s", package_property_suffix, name); } -#if defined (NET) MonoAssembly* Util::monodroid_load_assembly (MonoAssemblyLoadContextGCHandle alc_handle, const char *basename) { @@ -162,7 +127,6 @@ Util::monodroid_load_assembly (MonoAssemblyLoadContextGCHandle alc_handle, const } return assm; } -#endif // def NET MonoAssembly * Util::monodroid_load_assembly (MonoDomain *domain, const char *basename) @@ -191,72 +155,9 @@ Util::monodroid_load_assembly (MonoDomain *domain, const char *basename) return assm; } -#if !defined (NET) -MonoObject * -Util::monodroid_runtime_invoke (MonoDomain *domain, MonoMethod *method, void *obj, void **params, MonoObject **exc) -{ - MonoDomain *current = get_current_domain (); - if (domain == current) { - return mono_runtime_invoke (method, obj, params, exc); - } - - mono_domain_set (domain, FALSE); - MonoObject *r = mono_runtime_invoke (method, obj, params, exc); - mono_domain_set (current, FALSE); - return r; -} - -void -Util::monodroid_property_set (MonoDomain *domain, MonoProperty *property, void *obj, void **params, MonoObject **exc) -{ - MonoDomain *current = get_current_domain (); - if (domain == current) { - mono_property_set_value (property, obj, params, exc); - return; - } - - mono_domain_set (domain, FALSE); - mono_property_set_value (property, obj, params, exc); - mono_domain_set (current, FALSE); -} - -MonoDomain* -Util::monodroid_create_appdomain (MonoDomain *parent_domain, const char *friendly_name, int shadow_copy, const char *shadow_directories) -{ - MonoClass *appdomain_setup_klass = monodroid_get_class_from_name (parent_domain, "mscorlib", "System", "AppDomainSetup"); - MonoClass *appdomain_klass = monodroid_get_class_from_name (parent_domain, "mscorlib", "System", "AppDomain"); - MonoMethod *create_domain = mono_class_get_method_from_name (appdomain_klass, "CreateDomain", 3); - MonoProperty *shadow_copy_prop = mono_class_get_property_from_name (appdomain_setup_klass, "ShadowCopyFiles"); - MonoProperty *shadow_copy_dirs_prop = mono_class_get_property_from_name (appdomain_setup_klass, "ShadowCopyDirectories"); - - MonoObject *setup = mono_object_new (parent_domain, appdomain_setup_klass); - MonoString *mono_friendly_name = mono_string_new (parent_domain, friendly_name); - MonoString *mono_shadow_copy = mono_string_new (parent_domain, shadow_copy ? "true" : "false"); - MonoString *mono_shadow_copy_dirs = shadow_directories == nullptr ? nullptr : mono_string_new (parent_domain, shadow_directories); - - monodroid_property_set (parent_domain, shadow_copy_prop, setup, reinterpret_cast (&mono_shadow_copy), nullptr); - if (mono_shadow_copy_dirs != nullptr) - monodroid_property_set (parent_domain, shadow_copy_dirs_prop, setup, reinterpret_cast (&mono_shadow_copy_dirs), nullptr); - - void *args[3] = { mono_friendly_name, nullptr, setup }; - auto appdomain = reinterpret_cast(monodroid_runtime_invoke (parent_domain, create_domain, nullptr, args, nullptr)); - if (appdomain == nullptr) - return nullptr; - - return mono_domain_from_appdomain (appdomain); -} -#endif // ndef NET - MonoClass* Util::monodroid_get_class_from_name ([[maybe_unused]] MonoDomain *domain, const char* assembly, const char *_namespace, const char *type) { -#if !defined (NET) - MonoDomain *current = get_current_domain (); - - if (domain != current) - mono_domain_set (domain, FALSE); -#endif // ndef NET - MonoClass *result; MonoAssemblyName *aname = mono_assembly_name_new (assembly); MonoAssembly *assm = mono_assembly_loaded (aname); @@ -266,33 +167,9 @@ Util::monodroid_get_class_from_name ([[maybe_unused]] MonoDomain *domain, const } else result = nullptr; -#if !defined (NET) - if (domain != current) - mono_domain_set (current, FALSE); -#endif // ndef NET - mono_assembly_name_free (aname); - - return result; -} - -#if !defined (NET) -MonoClass* -Util::monodroid_get_class_from_image (MonoDomain *domain, MonoImage *image, const char *_namespace, const char *type) -{ - MonoDomain *current = get_current_domain (); - - if (domain != current) - mono_domain_set (domain, FALSE); - - MonoClass *result = mono_class_from_name (image, _namespace, type); - - if (domain != current) - mono_domain_set (current, FALSE); - return result; } -#endif // ndef NET jclass Util::get_class_from_runtime_field (JNIEnv *env, jclass runtime, const char *name, bool make_gref) diff --git a/src/monodroid/jni/util.hh b/src/monodroid/jni/util.hh index 796c5cf67da..d402a01484e 100644 --- a/src/monodroid/jni/util.hh +++ b/src/monodroid/jni/util.hh @@ -4,7 +4,7 @@ #ifndef TRUE #ifdef __cplusplus -constexpr int TRUE = 1; +static inline constexpr int TRUE = 1; #else #define TRUE 1 #endif // __cplusplus @@ -12,27 +12,31 @@ constexpr int TRUE = 1; #ifndef FALSE #ifdef __cplusplus -constexpr int FALSE = 0; +static inline constexpr int FALSE = 0; #else #define FALSE 0 #endif // __cplusplus #endif -#include -#include +#include +#include +#include +#include +#include #ifdef HAVE_BSD_STRING_H #include #endif #include #include #include -#include -#include #include + #include + #include #include #include +#include #include "monodroid.h" #include "jni-wrappers.hh" @@ -40,46 +44,15 @@ constexpr int FALSE = 0; #include "basic-utilities.hh" #endif -#if defined (NET) -#include -#endif // def NET - #include "java-interop-util.h" #include "logger.hh" -#if !defined (NET) -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - MONO_API void monodroid_strfreev (char **str_array); - MONO_API char **monodroid_strsplit (const char *str, const char *delimiter, size_t max_tokens); - MONO_API char *monodroid_strdup_printf (const char *format, ...); - MONO_API void monodroid_store_package_name (const char *name); - MONO_API int monodroid_get_namespaced_system_property (const char *name, char **value); - MONO_API FILE *monodroid_fopen (const char* filename, const char* mode); - - MONO_API int send_uninterrupted (int fd, void *buf, int len); - MONO_API int recv_uninterrupted (int fd, void *buf, int len); - MONO_API void set_world_accessable (const char *path); - MONO_API void create_public_directory (const char *dir); - MONO_API char *path_combine (const char *path1, const char *path2); -#ifdef __cplusplus -} -#endif // __cplusplus -#endif // NET - #ifdef __cplusplus namespace xamarin::android { class Util : public BasicUtilities { - static constexpr const char hex_chars [] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; - -#if defined (ANDROID) || defined (__linux__) || defined (__linux) - using timestruct = timespec; -#else - using timestruct = timeval; -#endif + 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: @@ -92,16 +65,8 @@ namespace xamarin::android void monodroid_store_package_name (const char *name); MonoAssembly *monodroid_load_assembly (MonoDomain *domain, const char *basename); -#if defined (NET) MonoAssembly *monodroid_load_assembly (MonoAssemblyLoadContextGCHandle alc_handle, const char *basename); -#else // def NET - MonoObject *monodroid_runtime_invoke (MonoDomain *domain, MonoMethod *method, void *obj, void **params, MonoObject **exc); -#endif // ndef NET MonoClass *monodroid_get_class_from_name (MonoDomain *domain, const char* assembly, const char *_namespace, const char *type); -#if !defined (NET) - MonoDomain *monodroid_create_appdomain (MonoDomain *parent_domain, const char *friendly_name, int shadow_copy, const char *shadow_directories); - MonoClass *monodroid_get_class_from_image (MonoDomain *domain, MonoImage* image, const char *_namespace, const char *type); -#endif int send_uninterrupted (int fd, void *buf, size_t len); ssize_t recv_uninterrupted (int fd, void *buf, size_t len); jclass get_class_from_runtime_field (JNIEnv *env, jclass runtime, const char *name, bool make_gref = false); @@ -130,11 +95,6 @@ namespace xamarin::android } private: - //char *monodroid_strdup_printf (const char *format, va_list vargs); -#if !defined (NET) - void monodroid_property_set (MonoDomain *domain, MonoProperty *property, void *obj, void **params, MonoObject **exc); -#endif // ndef NET - template void package_hash_to_hex (IdxType idx); diff --git a/src/monodroid/jni/xamarin-android-app-context.cc b/src/monodroid/jni/xamarin-android-app-context.cc index c1c401880e9..b4598519eb0 100644 --- a/src/monodroid/jni/xamarin-android-app-context.cc +++ b/src/monodroid/jni/xamarin-android-app-context.cc @@ -1,5 +1,7 @@ +#include #include #include +#include #include "monodroid-glue-internal.hh" #include "mono-image-loader.hh" @@ -46,7 +48,7 @@ MonodroidRuntime::get_function_pointer (uint32_t mono_image_index, uint32_t clas get_class_name (class_index), class_index ); - if (XA_UNLIKELY (class_index >= marshal_methods_number_of_classes)) { + if (class_index >= marshal_methods_number_of_classes) [[unlikely]] { log_fatal (LOG_DEFAULT, "Internal error: invalid index for class cache (expected at most %u, got %u)", marshal_methods_number_of_classes - 1, @@ -68,7 +70,7 @@ MonodroidRuntime::get_function_pointer (uint32_t mono_image_index, uint32_t clas MonoError error; void *ret = method != nullptr ? mono_method_get_unmanaged_callers_only_ftnptr (method, &error) : nullptr; - if (XA_LIKELY (ret != nullptr)) { + if (ret != nullptr) [[likely]] { if constexpr (NeedsLocking) { __atomic_store_n (&target_ptr, ret, __ATOMIC_RELEASE); } else { diff --git a/src/monodroid/jni/xamarin-app.hh b/src/monodroid/jni/xamarin-app.hh index d50fc39a683..86acc590ca8 100644 --- a/src/monodroid/jni/xamarin-app.hh +++ b/src/monodroid/jni/xamarin-app.hh @@ -19,7 +19,7 @@ static constexpr uint32_t MODULE_MAGIC_NAMES = 0x53544158; // 'XATS', little-end static constexpr uint32_t MODULE_INDEX_MAGIC = 0x49544158; // 'XATI', little-endian static constexpr uint8_t MODULE_FORMAT_VERSION = 2; // Keep in sync with the value in src/Xamarin.Android.Build.Tasks/Utilities/TypeMapGenerator.cs -#if defined (DEBUG) || !defined (ANDROID) +#if defined (DEBUG) struct BinaryTypeMapHeader { uint32_t magic; @@ -276,7 +276,7 @@ MONO_API MONO_API_EXPORT const JniRemappingTypeReplacementEntry jni_remapping_ty MONO_API MONO_API_EXPORT const uint64_t format_tag; -#if defined (DEBUG) || !defined (ANDROID) +#if defined (DEBUG) MONO_API MONO_API_EXPORT const TypeMap type_map; // MUST match src/Xamarin.Android.Build.Tasks/Utilities/TypeMappingDebugNativeAssemblyGenerator.cs #else MONO_API MONO_API_EXPORT const uint32_t map_module_count; @@ -303,7 +303,7 @@ MONO_API MONO_API_EXPORT DSOCacheEntry dso_cache[]; // // Support for marshal methods // -#if defined (RELEASE) && defined (ANDROID) && defined (NET) +#if defined (RELEASE) struct MarshalMethodsManagedClass { const uint32_t token; @@ -352,6 +352,6 @@ MONO_API MONO_API_EXPORT const MarshalMethodName mm_method_names[]; using get_function_pointer_fn = void(*)(uint32_t mono_image_index, uint32_t class_index, uint32_t method_token, void*& target_ptr); MONO_API MONO_API_EXPORT void xamarin_app_init (JNIEnv *env, get_function_pointer_fn fn) noexcept; -#endif // def RELEASE && def ANDROID && def NET +#endif // def RELEASE #endif // __XAMARIN_ANDROID_TYPEMAP_H diff --git a/src/monodroid/jni/xxhash.hh b/src/monodroid/jni/xxhash.hh index 4907e257ef4..377a7a908b4 100644 --- a/src/monodroid/jni/xxhash.hh +++ b/src/monodroid/jni/xxhash.hh @@ -32,6 +32,7 @@ */ #include +#include #include "platform-compat.hh" @@ -64,6 +65,12 @@ namespace xamarin::android return hash (input, Size - 1); } + template + force_inline static constexpr uint32_t hash (std::string_view const& input) noexcept + { + return hash (input.data (), input.length ()); + } + private: // 32-bit rotate left. template @@ -158,6 +165,12 @@ namespace xamarin::android return hash (input, Size - 1); } + template + force_inline static constexpr uint64_t hash (std::string_view const& input) noexcept + { + return hash (input.data (), input.length ()); + } + private: template force_inline static constexpr uint64_t rotl (uint64_t x) noexcept