Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 55 additions & 45 deletions src/monodroid/jni/embedded-assemblies.cc
Original file line number Diff line number Diff line change
Expand Up @@ -130,21 +130,45 @@ EmbeddedAssemblies::get_assembly_data (const MonoBundledAssembly *e, char*& asse
}
}

#if defined (NET6)
MonoAssembly*
#if defined (NET6) && defined (NET6_ALC_WORKS)
EmbeddedAssemblies::open_from_bundles (MonoAssemblyName* aname, MonoAssemblyLoadContextGCHandle alc_gchandle, MonoError *error)
#else // !(def NET6 && def NET6_ALC_WORKS)
EmbeddedAssemblies::open_from_bundles (MonoAssemblyName* aname, bool ref_only)
#endif // def NET6 && def NET6_ALC_WORKS
EmbeddedAssemblies::open_from_bundles (MonoAssemblyName* aname, MonoAssemblyLoadContextGCHandle alc_gchandle, [[maybe_unused]] MonoError *error)
{
#if defined (NET6)
// NET6 doesn't support reference-only loads, define the variable here to minimize ifdefs in the code below
#if defined (NET6_ALC_WORKS)
constexpr bool ref_only = false;
#else // def NET6_ALC_WORKS
ref_only = false;
#endif // ndef NET6_ALC_WORKS
auto loader = [&] (char *assembly_data, uint32_t assembly_data_size, const char *name) -> MonoImage* {
return mono_image_open_from_data_alc (
alc_gchandle,
assembly_data,
assembly_data_size,
0 /* need_copy */,
nullptr /* status */,
name
);
};

return open_from_bundles (aname, loader, false /* ref_only */);
}
#endif // def NET6

MonoAssembly*
EmbeddedAssemblies::open_from_bundles (MonoAssemblyName* aname, bool ref_only)
{
auto loader = [&] (char *assembly_data, uint32_t assembly_data_size, const char *name) -> MonoImage* {
return mono_image_open_from_data_with_name (
assembly_data,
assembly_data_size,
0,
nullptr,
ref_only,
name
);
};

return open_from_bundles (aname, loader, ref_only);
}

MonoAssembly*
EmbeddedAssemblies::open_from_bundles (MonoAssemblyName* aname, std::function<MonoImage*(char*, uint32_t, const char*)> loader, bool ref_only)
{
const char *culture = mono_assembly_name_get_culture (aname);
const char *asmname = mono_assembly_name_get_name (aname);

Expand Down Expand Up @@ -185,19 +209,7 @@ EmbeddedAssemblies::open_from_bundles (MonoAssemblyName* aname, bool ref_only)
}

get_assembly_data (e, assembly_data, assembly_data_size);

#if defined (NET6) && defined (NET6_ALC_WORKS)
image = mono_image_open_from_data_alc (
alc_gchandle,
assembly_data,
assembly_data_size,
0 /* need_copy */,
nullptr /* status */,
name.get ()
);
#else // (def NET6 && def NET6_ALC_WORKS)
image = mono_image_open_from_data_with_name (assembly_data, assembly_data_size, 0, nullptr, ref_only, name.get ());
#endif // !(def NET6 && def NET6_ALC_WORKS)
image = loader (assembly_data, assembly_data_size, name.get ());
if (image == nullptr) {
continue;
}
Expand All @@ -215,51 +227,49 @@ EmbeddedAssemblies::open_from_bundles (MonoAssemblyName* aname, bool ref_only)
log_info_nocheck (LOG_ASSEMBLY, "open_from_bundles: loaded assembly: %p\n", a);
}

#if defined (NET6) && defined (NET6_ALC_WORKS)
if (error != nullptr) {
error->error_code = a == nullptr ? MONO_ERROR_NONE : MONO_ERROR_FILE_NOT_FOUND;
}
#endif // def NET6 && def NET6_ALC_WORKS
return a;
}

#if defined (NET6) && defined (NET6_ALC_WORKS)
#if defined (NET6)
MonoAssembly*
EmbeddedAssemblies::open_from_bundles (MonoAssemblyLoadContextGCHandle alc_gchandle, MonoAssemblyName *aname, [[maybe_unused]] char **assemblies_path, [[maybe_unused]] void *user_data, MonoError *error)
{
log_warn (LOG_DEFAULT, __PRETTY_FUNCTION__);
return embeddedAssemblies.open_from_bundles (aname, alc_gchandle, error);
}
#else // def NET6 && def NET6_ALC_WORKS
#else // def NET6
MonoAssembly*
EmbeddedAssemblies::open_from_bundles_refonly (MonoAssemblyName *aname, [[maybe_unused]] char **assemblies_path, [[maybe_unused]] void *user_data)
{
return embeddedAssemblies.open_from_bundles (aname, true);
}
#endif // ndef NET6

MonoAssembly*
EmbeddedAssemblies::open_from_bundles_full (MonoAssemblyName *aname, [[maybe_unused]] char **assemblies_path, [[maybe_unused]] void *user_data)
{
return embeddedAssemblies.open_from_bundles (aname, false);
}

MonoAssembly*
EmbeddedAssemblies::open_from_bundles_refonly (MonoAssemblyName *aname, [[maybe_unused]] char **assemblies_path, [[maybe_unused]] void *user_data)
void
EmbeddedAssemblies::install_preload_hooks_for_appdomains ()
{
return embeddedAssemblies.open_from_bundles (aname, true);
mono_install_assembly_preload_hook (open_from_bundles_full, nullptr);
#if !defined (NET6)
mono_install_assembly_refonly_preload_hook (open_from_bundles_refonly, nullptr);
#endif // ndef NET6
}
#endif // !(def NET6 && def NET6_ALC_WORKS)

#if defined (NET6)
void
EmbeddedAssemblies::install_preload_hooks ()
EmbeddedAssemblies::install_preload_hooks_for_alc ()
{
#if defined (NET6) && defined (NET6_ALC_WORKS)
mono_install_assembly_preload_hook_v3 (
open_from_bundles,
nullptr /* user_data */,
0 /* append */
);
#else // def NET6 && def NET6_ALC_WORKS
mono_install_assembly_preload_hook (open_from_bundles_full, nullptr);
#if !defined (NET6) // Reference-only loads don't exist in NET6
mono_install_assembly_refonly_preload_hook (open_from_bundles_refonly, nullptr);
#endif // !def NET6
#endif // !(def NET6 && def NET6_ALC_WORKS)
}
#endif // def NET6

template<typename Key, typename Entry, int (*compare)(const Key*, const Entry*), bool use_extra_size>
const Entry*
Expand Down
21 changes: 13 additions & 8 deletions src/monodroid/jni/embedded-assemblies.hh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include <cstring>
#include <limits>
#include <functional>
#include <mono/metadata/object.h>
#include <mono/metadata/assembly.h>

Expand Down Expand Up @@ -50,7 +51,10 @@ namespace xamarin::android::internal {
#endif
const char* typemap_managed_to_java (MonoReflectionType *type, const uint8_t *mvid);

void install_preload_hooks ();
void install_preload_hooks_for_appdomains ();
#if defined (NET6)
void install_preload_hooks_for_alc ();
#endif // def NET6
MonoReflectionType* typemap_java_to_managed (MonoString *java_type);

/* returns current number of *all* assemblies found from all invocations */
Expand Down Expand Up @@ -93,11 +97,12 @@ namespace xamarin::android::internal {
MonoReflectionType* typemap_java_to_managed (const char *java_type_name);
size_t register_from (const char *apk_file, monodroid_should_register should_register);
void gather_bundled_assemblies_from_apk (const char* apk, monodroid_should_register should_register);
#if defined (NET6) && defined (NET6_ALC_WORKS)
#if defined (NET6)
MonoAssembly* open_from_bundles (MonoAssemblyName* aname, MonoAssemblyLoadContextGCHandle alc_gchandle, MonoError *error);
#else // def NET6 && def NET6_ALC_WORKS
#endif // def NET6
MonoAssembly* open_from_bundles (MonoAssemblyName* aname, bool ref_only);
#endif // !(def NET6 && def NET6_ALC_WORKS)
MonoAssembly* open_from_bundles (MonoAssemblyName* aname, std::function<MonoImage*(char*, uint32_t, const char*)> loader, bool ref_only);

#if defined (DEBUG) || !defined (ANDROID)
template<typename H>
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);
Expand All @@ -111,12 +116,12 @@ namespace xamarin::android::internal {
bool register_debug_symbols_for_assembly (const char *entry_name, MonoBundledAssembly *assembly, const mono_byte *debug_contents, int debug_size);

static md_mmap_info md_mmap_apk_file (int fd, uint32_t offset, uint32_t size, const char* filename, const char* apk);
#if defined (NET6) && defined (NET6_ALC_WORKS)
static MonoAssembly* open_from_bundles (MonoAssemblyLoadContextGCHandle alc_gchandle, MonoAssemblyName *aname, char **assemblies_path, void *user_data, MonoError *error);
#else // def NET6 && def NET6_ALC_WORKS
static MonoAssembly* open_from_bundles_full (MonoAssemblyName *aname, char **assemblies_path, void *user_data);
#if defined (NET6)
static MonoAssembly* open_from_bundles (MonoAssemblyLoadContextGCHandle alc_gchandle, MonoAssemblyName *aname, char **assemblies_path, void *user_data, MonoError *error);
#else // def NET6
static MonoAssembly* open_from_bundles_refonly (MonoAssemblyName *aname, char **assemblies_path, void *user_data);
#endif // !(def NET6 && def NET6_ALC_WORKS)
#endif // ndef NET6
static void get_assembly_data (const MonoBundledAssembly *e, char*& assembly_data, uint32_t& assembly_data_size);

void zip_load_entries (int fd, const char *apk_name, monodroid_should_register should_register);
Expand Down
16 changes: 14 additions & 2 deletions src/monodroid/jni/monodroid-glue-internal.hh
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,11 @@ namespace xamarin::android::internal
true
>;

using load_assemblies_context_type = MonoAssemblyLoadContextGCHandle;
static constexpr pinvoke_library_map::size_type LIBRARY_MAP_INITIAL_BUCKET_COUNT = 1;
#endif // def NET6
#else // def NET6
using load_assemblies_context_type = MonoDomain*;
#endif // ndef NET6

#if defined (DEBUG) && !defined (WINDOWS)
struct RuntimeOptions {
Expand Down Expand Up @@ -107,6 +110,9 @@ namespace xamarin::android::internal
};

private:
static constexpr char MONO_ANDROID_ASSEMBLY_NAME[] = "Mono.Android";
static constexpr char JAVA_INTEROP_ASSEMBLY_NAME[] = "Java.Interop";

static constexpr size_t SMALL_STRING_PARSE_BUFFER_LEN = 50;
static constexpr bool is_running_on_desktop =
#if ANDROID
Expand Down Expand Up @@ -222,7 +228,11 @@ namespace xamarin::android::internal
void disable_external_signal_handlers ();
void lookup_bridge_info (MonoDomain *domain, MonoImage *image, const OSBridge::MonoJavaGCBridgeType *type, OSBridge::MonoJavaGCBridgeInfo *info);
void load_assembly (MonoDomain *domain, jstring_wrapper &assembly);
void load_assemblies (MonoDomain *domain, bool preload, jstring_array_wrapper &assemblies);
#if defined (NET6)
void load_assembly (MonoAssemblyLoadContextGCHandle alc_handle, jstring_wrapper &assembly);
#endif // ndef NET6
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 (dynamic_local_string<PROPERTY_VALUE_BUFFER_LEN>& runtime_args);
Expand Down Expand Up @@ -302,6 +312,8 @@ namespace xamarin::android::internal
int current_context_id = -1;

#if defined (NET6)
MonoAssemblyLoadContextGCHandle default_alc = nullptr;

static std::mutex pinvoke_map_write_lock;
static pinvoke_api_map xa_pinvoke_map;
static pinvoke_library_map other_pinvoke_map;
Expand Down
Loading