set(GCC 1)
endif()
-if(DISABLE_INTERPRETER)
- unset(ENABLE_METADATA_UPDATE)
-endif()
-
add_definitions(-DHAVE_CONFIG_H)
if(GCC)
<MonoAOTCompilerProjDirectory>$([MSBuild]::NormalizeDirectory('$(RepoTasksDir)', 'AotCompilerTask'))</MonoAOTCompilerProjDirectory>
</PropertyGroup>
- <!-- Feature defaults for mono.proj and System.Private.CoreLib.csproj -->
- <PropertyGroup>
- <!-- default metadata update support for specific platforms -->
- <MonoMetadataUpdate Condition="'$(MonoMetadataUpdate)' == '' and ('$(TargetsAndroid)' == 'true' or '$(TargetsBrowser)' == 'true')">true</MonoMetadataUpdate>
- <MonoMetadataUpdate Condition="'$(MonoMetadataUpdate)' == '' and ('$(TargetsiOS)' == 'true' or '$(TargetstvOS)' == 'true' or '$(TargetsMacCatalyst)' == 'true')">true</MonoMetadataUpdate>
- <MonoMetadataUpdate Condition="'$(MonoMetadataUpdate)' == ''">false</MonoMetadataUpdate>
- </PropertyGroup>
</Project>
<DefineConstants Condition="'$(FeatureObjCMarshal)' == 'true'">$(DefineConstants);FEATURE_OBJCMARSHAL</DefineConstants>
</PropertyGroup>
- <!-- Experimental mono metadata update feature -->
- <PropertyGroup>
- <DefineConstants Condition="'$(MonoMetadataUpdate)' == 'true'">$(DefineConstants);FEATURE_METADATA_UPDATE</DefineConstants>
- </PropertyGroup>
-
<!-- ILLinker settings -->
<PropertyGroup>
<ILLinkTrimAssembly>true</ILLinkTrimAssembly>
if (runtimeAssembly == typeof(AssemblyExtensions).Assembly)
throw new InvalidOperationException (SR.InvalidOperation_AssemblyNotEditable);
-#if !FEATURE_METADATA_UPDATE
- throw new NotSupportedException (SR.NotSupported_MethodBodyReplacement);
-#else
unsafe
{
IntPtr monoAssembly = runtimeAssembly.GetUnderlyingNativeHandle ();
ApplyUpdate_internal(monoAssembly, metadataDeltaPtr, metadataDelta.Length, ilDeltaPtr, ilDelta.Length, pdbDeltaPtr, pdbDelta.Length);
}
}
-#endif
}
private static Lazy<string> s_ApplyUpdateCapabilities = new Lazy<string>(() => InitializeApplyUpdateCapabilities());
private static string InitializeApplyUpdateCapabilities()
{
-#if !FEATURE_METADATA_UPDATE
- return string.Empty;
-#else
return ApplyUpdateEnabled() != 0 ? "Baseline" : string.Empty ;
-#endif
}
-#if FEATURE_METADATA_UPDATE
[MethodImpl (MethodImplOptions.InternalCall)]
private static extern int ApplyUpdateEnabled ();
[MethodImpl (MethodImplOptions.InternalCall)]
private static unsafe extern void ApplyUpdate_internal (IntPtr base_assm, byte* dmeta_bytes, int dmeta_length, byte *dil_bytes, int dil_length, byte *dpdb_bytes, int dpdb_length);
-#endif
-
}
}
/* Enable runtime checks of mempool references between metadata images (must set env var MONO_CHECK_MODE=metadata) */
#cmakedefine ENABLE_CHECKED_BUILD_METADATA 1
-/* Enable runtime support for metadata updates */
-#cmakedefine ENABLE_METADATA_UPDATE 1
-
/* Enable static linking of mono runtime components */
#cmakedefine STATIC_COMPONENTS
option (ENABLE_CHECKED_BUILD_GC "Enable runtime GC Safe / Unsafe mode assertion checks (must set env var MONO_CHECK_MODE=gc)")
option (ENABLE_CHECKED_BUILD_THREAD "Enable runtime history of per-thread coop state transitions (must set env var MONO_CHECK_MODE=thread)")
option (ENABLE_CHECKED_BUILD_METADATA "Enable runtime checks of mempool references between metadata images (must set env var MONO_CHECK_MODE=metadata)")
-option (ENABLE_METADATA_UPDATE "Enable runtime support for metadata updates")
option (ENABLE_MSCORDBI "Generate mscordbi to support icordbg interface")
option (STATIC_COMPONENTS "Compile mono runtime components as static (not dynamic) libraries")
set (AOT_TARGET_TRIPLE "" CACHE STRING "Target triple for AOT cross compiler")
set (AOT_OFFSETS_FILE "" CACHE STRING "Offsets file for AOT cross compiler")
set (LLVM_PREFIX "" CACHE STRING "Enable LLVM support with LLVM installed at <LLVM_PREFIX>.")
-
- MonoAOTEnableLLVM - enable LLVM for an AOT-only Mono
- MonoAOTLLVMDir - [optional] the directory where LLVM is located, for an AOT-only Mono
- MonoVerboseBuild - enable verbose build
- - MonoMetadataUpdate - enable experimental method body replacement code (in Directory.Build.props)
- MonoThreadSuspend - coop,hybrid,preemptive - default thread suspend mode
-->
</ItemGroup>
<!-- Devloop features -->
- <ItemGroup Condition="'$(MonoMetadataUpdate)' == 'true'">
- <_MonoCMakeArgs Include="-DENABLE_METADATA_UPDATE=1" />
- </ItemGroup>
-
<ItemGroup Condition="'$(MonoMsCorDbi)' == 'true'">
<_MonoCMakeArgs Include="-DENABLE_MSCORDBI=1" />
</ItemGroup>
<MonoAOTCMakeArgs Condition="'$(MonoAOTEnableLLVM)' == 'true'" Include="-DLLVM_PREFIX=$(MonoAOTLLVMDir.TrimEnd('\/'))" />
<MonoAOTCMakeArgs Include="$(_MonoAOTCFLAGSOption)" />
<MonoAOTCMakeArgs Include="$(_MonoAOTCXXFLAGSOption)" />
- <!-- Devloop features -->
- <MonoAOTCMakeArgs Condition="'$(MonoMetadataUpdate)' == 'true'" Include="-DENABLE_METADATA_UPDATE=1" />
-
<!-- thread suspend -->
<MonoAOTCMakeArgs Include="-DGC_SUSPEND=$(MonoThreadSuspend)" />
</ItemGroup>
mono_close_exe_image (void)
{
gboolean do_close = exe_image != NULL;
-#ifdef ENABLE_METADATA_UPDATE
/* FIXME: shutdown hack. We mess something up and try to double-close/free it. */
do_close = do_close && !exe_image->has_updates;
-#endif
if (do_close)
mono_image_close (exe_image);
}
ICALL_EXPORT void ves_icall_System_Runtime_Intrinsics_X86_X86Base___cpuidex (int abcd[4], int function_id, int subfunction_id);
#endif
-#ifdef ENABLE_METADATA_UPDATE
ICALL_EXPORT void ves_icall_AssemblyExtensions_ApplyUpdate (MonoAssembly *assm, gconstpointer dmeta_bytes, int32_t dmeta_len, gconstpointer dil_bytes, int32_t dil_len, gconstpointer dpdb_bytes, int32_t dpdb_len);
ICALL_EXPORT gint32 ves_icall_AssemblyExtensions_ApplyUpdateEnabled (void);
-#endif
#endif // __MONO_METADATA_ICALL_DECL_H__
HANDLES(FILEDI_1, "get_marshal_info", ves_icall_System_Reflection_FieldInfo_get_marshal_info, MonoReflectionMarshalAsAttribute, 1, (MonoReflectionField))
HANDLES(FILEDI_2, "internal_from_handle_type", ves_icall_System_Reflection_FieldInfo_internal_from_handle_type, MonoReflectionField, 2, (MonoClassField_ref, MonoType_ref))
-#ifdef ENABLE_METADATA_UPDATE
ICALL_TYPE(ASSMEXT, "System.Reflection.Metadata.AssemblyExtensions", ASSMEXT_2)
NOHANDLES(ICALL(ASSMEXT_2, "ApplyUpdateEnabled", ves_icall_AssemblyExtensions_ApplyUpdateEnabled))
NOHANDLES(ICALL(ASSMEXT_1, "ApplyUpdate_internal", ves_icall_AssemblyExtensions_ApplyUpdate))
-#endif
ICALL_TYPE(MBASE, "System.Reflection.MethodBase", MBASE_1)
HANDLES(MBASE_1, "GetCurrentMethod", ves_icall_GetCurrentMethod, MonoReflectionMethod, 0, ())
return result;
}
-#ifdef ENABLE_METADATA_UPDATE
void
ves_icall_AssemblyExtensions_ApplyUpdate (MonoAssembly *assm,
gconstpointer dmeta_bytes, int32_t dmeta_len,
{
return mono_metadata_update_available ();
}
-#endif
MonoBoolean
ves_icall_System_Reflection_AssemblyName_ParseAssemblyName (const char *name, MonoAssemblyName *aname, MonoBoolean *is_version_defined_arg, MonoBoolean *is_token_defined_arg)
image->idx_guid_wide = ((heap_sizes & 0x02) == 2);
image->idx_blob_wide = ((heap_sizes & 0x04) == 4);
-#ifdef ENABLE_METADATA_UPDATE
if (G_UNLIKELY (image->minimal_delta)) {
/* sanity check */
g_assert (image->idx_string_wide);
g_assert (image->idx_guid_wide);
g_assert (image->idx_blob_wide);
}
-#endif
valid_mask = read64 (heap_tables + 8);
rows = (const guint32 *) (heap_tables + 24);
return h;
}
-#ifdef ENABLE_METADATA_UPDATE
static void
dump_encmap (MonoImage *image)
{
}
}
}
-#endif
static MonoImage *
do_mono_image_load (MonoImage *image, MonoImageOpenStatus *status,
if (!mono_image_load_cli_data (image))
goto invalid_image;
-#ifdef ENABLE_METADATA_UPDATE
dump_encmap (image);
-#endif
mono_image_load_names (image);
mono_image_invoke_unload_hook (image);
-#ifdef ENABLE_METADATA_UPDATE
mono_metadata_update_cleanup_on_close (image);
-#endif
/*
* The caches inside a MonoImage might refer to metadata which is stored in referenced
mono_image_close_except_pools_all (image->modules, image->module_count);
g_free (image->modules_loaded);
-#ifdef ENABLE_METADATA_UPDATE
if (image->has_updates)
mono_metadata_update_image_close_except_pools_all (image);
-#endif
mono_os_mutex_destroy (&image->szarray_cache_lock);
mono_os_mutex_destroy (&image->lock);
mono_image_close_all (image->files, image->file_count);
mono_image_close_all (image->modules, image->module_count);
-#ifdef ENABLE_METADATA_UPDATE
mono_metadata_update_image_close_all (image);
-#endif
#ifndef DISABLE_PERFCOUNTERS
/* FIXME: use an explicit subtraction method as soon as it's available */
g_assert (mono_metadata_token_table (method->token) == MONO_TABLE_METHOD);
idx = mono_metadata_token_index (method->token);
-#ifdef ENABLE_METADATA_UPDATE
if (G_UNLIKELY (img->has_updates))
loc = mono_metadata_update_get_updated_method_rva (img, idx);
-#endif
if (!loc) {
rva = mono_metadata_decode_row_col (&img->tables [MONO_TABLE_METHOD], idx - 1, MONO_METHOD_RVA);
int has_updates;
};
-#ifndef ENABLE_METADATA_UPDATE
-static inline gboolean
-mono_metadata_has_updates (void)
-{
- return FALSE;
-}
-
-static inline void
-mono_image_effective_table (const MonoTableInfo **t, int *idx)
-{
-}
-#else /* ENABLE_METADATA_UPDATE */
-
extern MonoMetadataUpdateData mono_metadata_update_data_private;
/* returns TRUE if there's at least one update */
void
mono_image_load_enc_delta (MonoImage *base_image, gconstpointer dmeta, uint32_t dmeta_len, gconstpointer dil, uint32_t dil_len, MonoError *error);
-#endif /* ENABLE_METADATA_UPDATE */
gboolean
mono_image_load_cli_header (MonoImage *image, MonoCLIImageInfo *iinfo);
void
mono_metadata_clean_generic_classes_for_image (MonoImage *image);
-#ifndef ENABLE_METADATA_UPDATE
-static inline gboolean
-mono_metadata_table_bounds_check (MonoImage *image, int table_index, int token_index)
-{
- /* token_index is 1-based. TRUE means the token is out of bounds */
- return token_index > image->tables [table_index].rows_;
-}
-#else
gboolean
mono_metadata_table_bounds_check_slow (MonoImage *image, int table_index, int token_index);
return TRUE;
return mono_metadata_table_bounds_check_slow (image, table_index, token_index);
}
-#endif
MONO_COMPONENT_API
const char * mono_meta_table_name (int table);
return mono_component_hot_reload ()->component.available ();
}
-#ifdef ENABLE_METADATA_UPDATE
-
MonoMetadataUpdateData mono_metadata_update_data_private;
void
return mono_component_hot_reload ()->delta_heap_lookup (base_image, get_heap, orig_index, image_out, index_out);
}
-#else /* ENABLE_METADATA_UPDATE */
-
-void
-mono_metadata_update_init (void)
-{
- MonoComponentHotReload *comp = mono_component_hot_reload ();
- comp->set_fastpath_data (NULL);
-}
-
-#endif /* ENABLE_METADATA_UPDATE */
gboolean
mono_metadata_update_available (void);
-#ifdef ENABLE_METADATA_UPDATE
-
gboolean
mono_metadata_update_enabled (int *modifiable_assemblies_out);
gboolean
mono_metadata_update_delta_heap_lookup (MonoImage *base_image, MetadataHeapGetterFunc get_heap, uint32_t orig_index, MonoImage **image_out, uint32_t *index_out);
-#else /* ENABLE_METADATA_UPDATE */
-
-static inline gboolean
-mono_metadata_update_enabled (int *modifiable_assemblies_out)
-{
- if (modifiable_assemblies_out)
- *modifiable_assemblies_out = 0;
- return FALSE;
-}
-
-static inline gboolean
-mono_metadata_update_no_inline (MonoMethod *caller, MonoMethod *callee)
-{
- return FALSE;
-}
-
-#endif /* ENABLE_METADATA_UPDATE */
-
#endif /*__MONO_METADATA_UPDATE_H__*/
return size;
}
-#ifdef ENABLE_METADATA_UPDATE
/* returns true if given index is not in bounds with provided table/index pair */
gboolean
mono_metadata_table_bounds_check_slow (MonoImage *image, int table_index, int token_index)
return mono_metadata_update_table_bounds_check (image, table_index, token_index);
}
-#endif
/**
* mono_metadata_compute_table_bases:
return mono_metadata_locate (meta, token >> 24, token & 0xffffff);
}
-
-
-#ifdef ENABLE_METADATA_UPDATE
static MonoStreamHeader *
get_string_heap (MonoImage *image)
{
return mono_metadata_update_delta_heap_lookup (base_image, get_heap, orig_index, image_out, index_out);
}
-#endif
-
/**
* mono_metadata_string_heap:
* \param meta metadata context
const char *
mono_metadata_string_heap (MonoImage *meta, guint32 index)
{
-#ifdef ENABLE_METADATA_UPDATE
if (G_UNLIKELY (index >= meta->heap_strings.size && meta->has_updates)) {
MonoImage *dmeta;
guint32 dindex;
meta = dmeta;
index = dindex;
}
-#endif
g_assertf (index < meta->heap_strings.size, " index = 0x%08x size = 0x%08x meta=%s ", index, meta->heap_strings.size, meta && meta->name ? meta->name : "unknown image" );
g_return_val_if_fail (index < meta->heap_strings.size, "");
return img->sheap.data + index;
}
-#ifdef ENABLE_METADATA_UPDATE
if (G_UNLIKELY (index >= meta->heap_strings.size && meta->has_updates)) {
MonoImage *dmeta;
guint32 dindex;
meta = dmeta;
index = dindex;
}
-#endif
if (G_UNLIKELY (!(index < meta->heap_strings.size))) {
const char *image_name = meta && meta->name ? meta->name : "unknown image";
const char *
mono_metadata_user_string (MonoImage *meta, guint32 index)
{
-#ifdef ENABLE_METADATA_UPDATE
if (G_UNLIKELY (index >= meta->heap_us.size && meta->has_updates)) {
MonoImage *dmeta;
guint32 dindex;
meta = dmeta;
index = dindex;
}
-#endif
g_assert (index < meta->heap_us.size);
g_return_val_if_fail (index < meta->heap_us.size, "");
return meta->heap_us.data + index;
* assertion is hit, consider updating caller to use
* mono_metadata_blob_heap_null_ok and handling a null return value. */
g_assert (!(index == 0 && meta->heap_blob.size == 0));
-#ifdef ENABLE_METADATA_UPDATE
if (G_UNLIKELY (index >= meta->heap_blob.size && meta->has_updates)) {
MonoImage *dmeta;
guint32 dindex;
meta = dmeta;
index = dindex;
}
-#endif
g_assert (index < meta->heap_blob.size);
return meta->heap_blob.data + index;
}
}
if (G_UNLIKELY (index == 0 && meta->heap_blob.size == 0))
return NULL;
-#ifdef ENABLE_METADATA_UPDATE
if (G_UNLIKELY (index >= meta->heap_blob.size && meta->has_updates)) {
MonoImage *dmeta;
guint32 dindex;
meta = dmeta;
index = dindex;
}
-#endif
if (G_UNLIKELY (!(index < meta->heap_blob.size))) {
const char *image_name = meta && meta->name ? meta->name : "unknown image";
mono_error_set_bad_image_by_name (error, image_name, "blob heap index %u out of bounds %u: %s", index, meta->heap_blob.size, image_name);
#include <mono/metadata/threads-types.h>
#include <mono/metadata/exception.h>
#include <mono/metadata/environment.h>
+#include <mono/metadata/metadata-update.h>
#include <mono/metadata/monitor.h>
#include <mono/metadata/mono-hash-internals.h>
#include <mono/metadata/gc-internals.h>
mono_threads_unlock ();
-#ifdef MONO_METADATA_UPDATE
/* Roll up to the latest published metadata generation */
mono_metadata_update_thread_expose_published ();
-#endif
THREAD_DEBUG (g_message ("%s: Attached thread ID %" G_GSIZE_FORMAT " (handle %p)", __func__, internal->tid, internal->handle));
static gboolean
module_apply_changes (MonoImage *image, MonoArray *dmeta, MonoArray *dil, MonoArray *dpdb, MonoError *error)
{
-#ifdef ENABLE_METADATA_UPDATE
/* TODO: use dpdb */
gpointer dmeta_bytes = (gpointer)mono_array_addr_internal (dmeta, char, 0);
int32_t dmeta_len = mono_array_length_internal (dmeta);
int32_t dpdb_len G_GNUC_UNUSED = !dpdb ? 0 : mono_array_length_internal (dpdb);
mono_image_load_enc_delta (image, dmeta_bytes, dmeta_len, dil_bytes, dil_len, error);
return is_ok (error);
-#else
- mono_error_set_not_supported (error, "");
- return FALSE;
-#endif
}
*/
}
-#ifdef ENABLE_METADATA_UPDATE
static void
metadata_update_backup_frames (MonoThreadInfo *info, InterpFrame *frame)
{
/* (2) invalidate all the registered imethods */
}
-#else
-static void
-metadata_update_prepare_to_invalidate (void)
-{
-}
-#endif
static void
error_init (error);
-#ifdef ENABLE_METADATA_UPDATE
mono_metadata_update_thread_expose_published ();
-#endif
if (mono_class_is_open_constructed_type (m_class_get_byval_arg (method->klass))) {
mono_error_set_invalid_operation (error, "%s", "Could not execute the method because the containing type is not fully instantiated.");
## Prerequisites
-To run the tests you will need to:
-
-1. Build a runtime with the `MonoMetadataUpdate` property set to true: `/p:MonoMetadataUpdate=true`.
-2. Put the [hotreload-delta-gen](https://github.com/dotnet/hotreload-utils/tree/main/src/hotreload-delta-gen) command line tool somewhere on your `PATH`.
-
- Build the tool with `dotnet publish --self-contained -r <RID>` and then add the `publish/hotreload-delta-gen` directory to your `PATH`.
- If you don't want to add it to your `PATH`, you can set the `HotReloadDeltaGenFullPath` msbuild property in `DeltaHelper.targets` to the full path name of the published executable.
-
-The tool, runtime changes and samples should work on Mac and Linux. Windows might work, but it hasn't been tested.
+To run the tests you will need to build a Mono runtime with the `hot_reload` component.
## Building
-Build the runtime with the `/p:MonoMetadataUpdate=true` option.
-
Both Debug and Release configurations should work.
For desktop:
```console
-build.sh -s Mono+Libs /p:MonoMetadataUpdate=true
+build.sh -s Mono+Libs
```
<MicrosoftNetCoreAppRuntimePackNativeDir>$([MSBuild]::NormalizeDirectory('$(MicrosoftNetCoreAppRuntimePackRidDir)', 'native'))</MicrosoftNetCoreAppRuntimePackNativeDir>
<WasmEnableES6 Condition="'$(WasmEnableES6)' == ''">false</WasmEnableES6>
<FilterSystemTimeZones Condition="'$(FilterSystemTimeZones)' == ''">false</FilterSystemTimeZones>
- <WasmEnableMetadataUpdate Condition="'$(MonoMetadataUpdate)' == 'true'">true</WasmEnableMetadataUpdate>
<EmccCmd>emcc</EmccCmd>
<WasmObjDir>$(ArtifactsObjDir)wasm</WasmObjDir>
<_EmccDefaultsRspPath>$(NativeBinDir)src\emcc-default.rsp</_EmccDefaultsRspPath>
</PropertyGroup>
- <PropertyGroup>
- <!-- TODO: set to "false" for publishing/production builds -->
- <MonoMetadataUpdate Condition="'$(MonoMetadataUpdate)' == ''">true</MonoMetadataUpdate>
- </PropertyGroup>
-
<Target Name="CheckEnv">
<Error Condition="'$(TargetArchitecture)' != 'wasm'" Text="Expected TargetArchitecture==wasm, got '$(TargetArchitecture)'"/>
<Error Condition="'$(TargetOS)' != 'Browser'" Text="Expected TargetOS==Browser, got '$(TargetOS)'"/>
<ItemGroup Condition="'$(OS)' != 'Windows_NT'">
<_EmccFlags Include="--profiling-funcs" />
<_EmccFlags Include="@(_EmccCommonFlags)" />
-
- <_EmccFlags Include="-DENABLE_METADATA_UPDATE=1" Condition="'$(WasmEnableMetadataUpdate)' == 'true'" />
</ItemGroup>
<ItemGroup Condition="'$(OS)' == 'Windows_NT'">
<Copy SourceFiles="runtime/driver.c;
runtime/pinvoke.c;
runtime/corebindings.c;
- runtime/binding_support.js;
+ runtime/binding_support.js;
runtime/dotnet_support.js;
runtime/library_mono.js;
$(SystemNativeDir)\pal_random.js;"