Skip to content

Commit

Permalink
[mono] Fix LoadAssemblyRaw to not pin or copy (#20516)
Browse files Browse the repository at this point in the history
Copying of the assembly and symbols happens later, in `mono_alc_load_raw_bytes`, and the pinning is no longer necessary so long as we have the handle.

Followup from dotnet/runtime#43592 (comment), cc: @lambdageek

Co-authored-by: CoffeeFlux <[email protected]>
  • Loading branch information
monojenkins and CoffeeFlux authored Oct 28, 2020
1 parent 95c2300 commit fe26fa8
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 24 deletions.
31 changes: 9 additions & 22 deletions mono/metadata/appdomain.c
Original file line number Diff line number Diff line change
Expand Up @@ -2789,33 +2789,20 @@ ves_icall_System_AppDomain_LoadAssemblyRaw (MonoAppDomainHandle ad,
{
MonoAssembly *ass;
MonoReflectionAssemblyHandle refass = MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE);
MonoDomain *domain = MONO_HANDLE_GETVAL(ad, data);
guint32 raw_assembly_len = mono_array_handle_length (raw_assembly);

/* Copy the data ourselves to unpin the raw assembly byte array as soon as possible */
guint8 *assembly_data = (guint8*) g_try_malloc (raw_assembly_len);
if (!assembly_data) {
mono_error_set_out_of_memory (error, "Could not allocate %ud bytes to copy raw assembly data", raw_assembly_len);
return refass;
}
MonoGCHandle gchandle;
mono_byte *raw_data = (mono_byte*) MONO_ARRAY_HANDLE_PIN (raw_assembly, gchar, 0, &gchandle);
memcpy (assembly_data, raw_data, raw_assembly_len);
mono_gchandle_free_internal (gchandle); /* unpin */
MONO_HANDLE_ASSIGN (raw_assembly, NULL_HANDLE); /* don't reference the data anymore */

MonoDomain *domain = MONO_HANDLE_GETVAL (ad, data);
MonoAssemblyLoadContext *alc = mono_domain_default_alc (domain);

mono_byte *raw_symbol_data = NULL;
guint32 symbol_len = 0;
MonoGCHandle symbol_gchandle = 0;
guint8 *raw_assembly_ptr = (guint8 *)mono_array_handle_addr (raw_assembly, sizeof (guint8), 0);
guint32 raw_assembly_len = mono_array_handle_length (raw_assembly);

guint8 *raw_symbols_ptr = NULL;
guint32 raw_symbols_len = 0;
if (!MONO_HANDLE_IS_NULL (raw_symbol_store)) {
symbol_len = mono_array_handle_length (raw_symbol_store);
raw_symbol_data = (mono_byte*) MONO_ARRAY_HANDLE_PIN (raw_symbol_store, mono_byte, 0, &symbol_gchandle);
raw_symbols_ptr = (guint8 *)mono_array_handle_addr (raw_symbol_store, sizeof (guint8), 0);
raw_symbols_len = mono_array_handle_length (raw_symbol_store);
}

ass = mono_alc_load_raw_bytes (alc, assembly_data, raw_assembly_len, raw_symbol_data, symbol_len, refonly, error);
mono_gchandle_free_internal (symbol_gchandle);
ass = mono_alc_load_raw_bytes (alc, raw_assembly_ptr, raw_assembly_len, raw_symbols_ptr, raw_symbols_len, refonly, error);
goto_if_nok (error, leave);

refass = mono_assembly_get_object_handle (domain, ass, error);
Expand Down
10 changes: 8 additions & 2 deletions mono/metadata/handle.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,13 +414,19 @@ mono_gchandle_get_target_handle (MonoGCHandle gchandle)
return MONO_HANDLE_NEW (MonoObject, mono_gchandle_get_target_internal (gchandle));
}

gpointer
mono_array_handle_addr (MonoArrayHandle handle, int size, uintptr_t index)
{
MonoArray *raw = MONO_HANDLE_RAW (handle);
return mono_array_addr_with_size_internal (raw, size, index);
}

gpointer
mono_array_handle_pin_with_size (MonoArrayHandle handle, int size, uintptr_t idx, MonoGCHandle *gchandle)
{
g_assert (gchandle != NULL);
*gchandle = mono_gchandle_from_handle (MONO_HANDLE_CAST(MonoObject,handle), TRUE);
MonoArray *raw = MONO_HANDLE_RAW (handle);
return mono_array_addr_with_size_internal (raw, size, idx);
return mono_array_handle_addr (handle, size, idx);
}

gunichar2*
Expand Down
4 changes: 4 additions & 0 deletions mono/metadata/handle.h
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,10 @@ mono_array_handle_memcpy_refs (MonoArrayHandle dest, uintptr_t dest_idx, MonoArr
gpointer
mono_array_handle_pin_with_size (MonoArrayHandle handle, int size, uintptr_t index, MonoGCHandle *gchandle);

// Returns a pointer to the element with the given index, but does not pin
gpointer
mono_array_handle_addr (MonoArrayHandle handle, int size, uintptr_t index);

#define MONO_ARRAY_HANDLE_PIN(handle,type,index,gchandle_out) ((type*)mono_array_handle_pin_with_size (MONO_HANDLE_CAST(MonoArray,(handle)), sizeof (type), (index), (gchandle_out)))

void
Expand Down

0 comments on commit fe26fa8

Please sign in to comment.