Skip to content
Branch: master
Commits on Jan 17, 2020
  1. [netcore] Mark InitializeCurrentThread NoInlining (#18493)

    lambdageek authored and akoeplinger committed Jan 17, 2020
    Follow-up for #18480
    We might want to replace calls to this with an intrinsic
  2. [runtime] NOHANDLES for ves_icall_System_Threading_Thread_GetCurrentT…

    lambdageek committed Jan 17, 2020
    …hread (#18480)
    * [runtime] NOHANDLES for ves_icall_System_Threading_Thread_GetCurrentThread
    This function (and its call to mono_handle_new) was showing up in the
    flamegraph for some async-heavy benchmarks
  3. [interp] Add missing files to tarball (#18482)

    lambdageek committed Jan 17, 2020
Commits on Jan 15, 2020
  1. [loader] ReflectionOnlyLoad(byte[]) should not apply binding redirects (

    lambdageek authored and akoeplinger committed Jan 15, 2020
    * [loader] ReflectionOnlyLoad(byte[]) should not apply binding redirects
    Match .NET Framework behavior.
    Addresses #18388
    * [tests] ReflectionOnlyLoad(byte[]) should not apply binding redirects
    Regression test for #18388
Commits on Jan 13, 2020
  1. [netcore] Require use of MonoClass getters in Debug builds (#18267)

    lambdageek authored and akoeplinger committed Jan 13, 2020
    1. Update `` to use `--enable-checked-build=private_types` which forces the use of getter methods to access `MonoClass` fields.
    2. Fix up some places that were accessing MonoClass directly.
    3. Get rid of a spurious comma operator usage from an earlier refactoring:
          z = a, b, c;
       is the same as
          z = a; b; c;
       which is the same as just `z = a;` if `b` and `c` have no side-effects.
Commits on Jan 3, 2020
  1. [metadata] Size 0 Blob heap is ok when resolving assembly refs (#18313)

    lambdageek committed Jan 3, 2020
    * [metadata] Size 0 Blob heap is ok when resolving assembly refs
    Sometimes ILasm can produce images with a Blob heap of size 0.  In cases where
    we're loading assembly references from such an image, the hash (which is
    optional) can be at index = 0 and the Blob heap size is also 0.
    Also: add the hash value to the output of `monodis --assemblyref`
    * [metadata] Add a separate assertion for the index == size == 0 case
    And a comment explaining how it is likely to be triggered.  If the assembly is
    reasonable the caller of mono_metadata_blob_heap should be updated to use
    mono_metadata_blob_heap_null_ok instead
    * [bcl] Allow Mono's ILASM to produce a size 0 Blob heap
    ECMA 335 II.24.2.4 says that the user string and blob heaps should have an
    entry at index 0 consisting of the single byte 0.  However .NET Framework (and
    .NET Core) ilasm will entirely omit the Blob heap (that is, create a blob heap
    entry of size 0) if it is not needed.  This PR changes Mono's ILASM to emit the
    initial byte on demand only if one of the MetaDataStream.Add() methods is
    called. Otherwise we will also emit a stream of size 0.
    This is needed to compile some test cases.
    * [tests] Add regression test for loading assemblies with size 0 Blob heap
    Depends on ILASM that can emit a size 0 Blob heap
Commits on Dec 30, 2019
  1. [eglib] Don't define _FORTIFY_SOURCE on Cygwin builds (#18308)

    lambdageek committed Dec 30, 2019
    See msys2/MINGW-packages#5803
    Without -lssp (or -fstack-protector), -D_FORTIFY_SOURCE=2 leads to linker
Commits on Dec 23, 2019
  1. [domain] Don't add NULL runtime to runtimes list (#18260)

    lambdageek committed Dec 23, 2019
    Also when iterating over the runtimes, actually look at the current element,
    not the first element.
    Also mention the unsupported runtime version in the warning message when it is
    passed to mono_init_internal.
    Fixes #17916
Commits on Dec 20, 2019
  1. [tests] Add test files to tarball (#18261)

    lambdageek authored and akoeplinger committed Dec 20, 2019
    Some test sources weren't included.
    Fixes #18202
Commits on Dec 13, 2019
  1. [cominterop] Attach to runtime from IUnknown and IDispatch methods (#…

    lambdageek committed Dec 13, 2019
    * [cominterop][test] Calling QueryInterface from an unattached thread asserts
    If we pass a managed COM object to native code and the native code calls one of
    the IUnknown methods, we assert because the thread is not attached but we want
    to enter GC Unsafe mode.
    * [cominterop] Attach to runtime from IUnkown and IDispatch methods
    If the COM objects for a managed object is passed to a thread that hasn't
    interacted with Mono before, we need to attach before doing GC thread state
    Addresses #18137
    * [test] Call managed method through COM wrapper from unattached thread
    This works, but I don't think we had a test previously.  Call a managed method
    via a COM interface from a thread that is not attached to the runtime, to
    ensure that it is attached.
Commits on Dec 10, 2019
  1. [mini] Fix delegate trampoline virtual call via delgate Invoke (#18073)

    lambdageek authored and lewurm committed Dec 10, 2019
    * [mini] Fix delegate trampoline virtual call via delgate Invoke
    If we need to jit the Invoke method of a delegate, we get tramp_info with a
    NULL method.
    Background: normally when we create a delegate around a virtual method,
    handle_delegate_ctor will just create a virtual invoke trampoline with
    mono_arch_get_delegate_virtual_invoke_impl which doesn't get here.  But if
    we're asked to compile the delegate's Invoke method, then compile_special ()
    will create a tramp_info with a null method, and return a delegate trampoline.
    That's the case here - we had
      var del = SomeDelegate(obj.VirtualMethod);
      var invoke_method = del.GetType().GetMethod ("Invoke");
      invoke_method.Invoke (del, args);
      var del = SomeDelegate(obj.VirtualMethod);
      var another_del = OtherDelegate (del.Invoke);
      another_del (args);
    in both cases, we end up in mono_delegate_trampoline with tramp_info->method ==
    in the second case the IL is like this:
       newobj instance void Derived::'.ctor'
       ldvirtftn instance void class Base::VirtualMethod()
       newobj instance void class SomeDelegate::'.ctor'(object, native int)
    So delegate->target is a derived instance but delegate->method is some base
    class method.
    Addresses #17718
    * [tests] Add tests for compiling delegate's Invoke method
    Where the delegate calls a virtual method
Commits on Dec 6, 2019
  1. [threads] Add back mono_threads_attach_tools_thread as a public API (#…

    lambdageek committed Dec 6, 2019
    * [utils] Add back mono_threads_attach_tools_thread
    In a5da7b2
    we got rid of "tools" threads internally to the runtime.
    However since the API was previously marked with MONO_API it was an internal
    API that some embedders depended on.
    This PR adds back an (external-only) limited form of tools thread.
    The runtime is aware of the Tools thread in that FOREACH_THREAD_* macros will
    iterate over them, and the thread has a coop thread state machine. (That is,
    mono_thread_info_current() and GC Safe and GC Unsafe transitions all work.)
    However the thread is:
    1. Not stopped by the GC
    2. Is not interrupted by profiler sampling.
    3. Does not have a "current domain"
    4. (As a consequence of the above) cannot call managed methods or touch managed
    Such threads are useful for low-level interaction with the runtime such as
    querying metadata, the JIT state and other coordination.
    mono_threads_attach_tools_thread should be called no more than once.  It should
    not be called on a thread that is already attached with mono_thread_atach, and
    vice versa.
    Addresses #18011
    * [threads] Make mono_threads_attach_tools_thread into a public API
Commits on Dec 4, 2019
  1. [] Build on FreeBSD/PowerPC64 (#18015)

    lambdageek committed Dec 4, 2019
    Community contribution from #18009
    from @igorzigorz
Commits on Nov 27, 2019
  1. [threadpool] Decrement max_working when worker times out (#17927)

    lambdageek authored and monojenkins committed Nov 27, 2019
    [threadpool] Decrement max_working when worker times out
    The corresponding code in CoreCLR:
    The issue is that counter._.max_working is only ever changed by:
    1. the monitor_thread when it detects starvation (increment by 1).
    2. the hill climbing algorithm (increment or decrement).
    Creating a periodic load of creating many workers at once followed by a minute
    or more of quiescence increases the variable worker.counters._.max_working in
    monitor_thread(). Once that counter matches worker.limit_worker_max,
    monitor_thread() keeps looping without unparking or creating a thread, even
    though the actual number of threads/workers is small. If the existing threads
    are all waiting on work that needs a new thread, then a deadlock occurs.
    With this change, when a parked worker times out, it will lower max_working to
    the number of active (working + parked + starting) threads minus itself (but no
    less than limit_worker_min). As a result, monitor_thread will only increment
    max_working as long as none of the already running workers are timing out.
    Attempt to address #17833
    Also allow monitor_thread to start workers if there aren't enough active, even if the max worker limit has been reached.
    Work around a pathological condition where the work_item_count is non-zero, and
    the max_working limit has been reached, but the number of active threads is
    still below the max.  In that case, unpark some workers and start some new
    May address
Commits on Nov 7, 2019
  1. [profiler] Fix log profiling of native to managed wrappers (#17740)

    lambdageek committed Nov 7, 2019
    * [profiler] Add test case for pinvokes and reverse pinvokes
    * [profiler] Fix crash in native to managed wrappers
    When we call back to managed from a pinvoke, we're in GC Safe mode and the
    profiler instrumentation is inserted in the wrapper before it does the
    transition to GC Unsafe.  So we need an extra transition before the profiler
    calls its locking functions
    Fixes #17687
    * [coop] Mark internal GC Unsafe functions with MONO_PROFILER_API
    Allow the profiler to transition to GC Unsafe mode
    * [profiler] fix profiler modules directory
    we used to specify mono/mini/.libs but that's not where the profiler plugins live, they're in mono/profiler/.libs.   We probably picked up the profiler plugins from the system Mono install.
Commits on Oct 26, 2019
  1. [runtime] Unbalanced GC Unsafe transitions before shutdown (#17566)

    lambdageek committed Oct 26, 2019
    When embedders call mono_runtime_quit or mono_jit_cleanup, we need to do unbalanced transitions to GC Unsafe, because after mini_cleanup runs we don't have GC thread states anymore and MONO_EXIT_GC_UNSAFE will assert.
    * [runtime] Do an unbalanced GC Unsafe transition in mono_jit_cleanup
    After mini_cleanup, we don't have GC thread states anymore because all that
    stuff was cleaned up, so MONO_EXIT_GC_UNSAFE would assert
    * [runtime] Mark mono_runtime_quit external only.
    Runtime should use mono_runtime_quit_internal.
    After we call the quit_function (aka mini_cleanup) we don't have any GC thread
    states anymore because all that stuff got cleaned up.  So MONO_EXIT_GC_UNSAFE
    can't work.
Commits on Oct 25, 2019
  1. [runtime] Make mono_thread_manage external only (#17554)

    lambdageek committed Oct 25, 2019
    * [runtime] Make mono_thread_manage external only
    runtime should use mono_thread_manage_internal
Commits on Oct 22, 2019
  1. [reflection] mono_method_get_base_method on a GTD should use canonica…

    lambdageek committed Oct 22, 2019
    …l ginst (#17475)
    * [test] GetCustomAttributes on generic type definition
    * [reflection] mono_method_get_base_method on a GTD should use canonical ginst
    The issue is in how we pass along the generic instantiation.  So there are two
    parts here: we start with a method on a GTD which has to decompose into the GTD
    and it's instantiation with its own generic parameters, and then we go up to
    its parent and grandparent inflating and decomposing the resulting
    instantiation. The instantiations keep passing the last parameter as the number
    of parameters shrinks so that the gparam index from the original type is now
    out of bounds for the parent and grandparent.  If we mess up, we'll get a
    BadImageFormatException from the runtime
    Fixes #17278
  2. [coop] Use bitfields for coop state machine state representation (#17298

    lambdageek committed Oct 22, 2019
    * [checked] Mask the thread state in GC thread state assertions
    Because we have extra bits (like suspend count and the no_checkpoints bit) on
    the thread state, we have to mask it to get the actual thread state enum value
    * [coop] Use bitfields to represent coop thread state
    Instead of using a 32-bit int, use bitfields and type-punning through a union
    type.  We need to type pun because we need to access the entire state as a 32-bit int so that we can do atomic CAS.
    * use atomic load of thread state in unwrap_thread_state.
    Saw one stack trace on CI on the full coop lane where check_thread_state saw STATE_RUNNING
    but with a positive suspend count.  Another thread was starting a GC a
    the time.  Seems like we saw the state as runnning, but the suspend
    count as if we were already in async_suspend_requested.
    Thread 22 (Thread 0x7f43c03ff700 (LWP 39860)):
Commits on Oct 18, 2019
  1. [bcl] Add null reference checks to Interlocked.Exchange<T> (#17400)

    lambdageek authored and vargaz committed Oct 18, 2019
    * [bcl] Add null reference checks to Interlocked.Exchange<T>
    and Interlocked.CompareExchange<T>
    This is to mimic the old behavior in unmanaged when the intrinsic cannot be
    The issue was detected via the coreclr acceptance test:
    * and netcore
Commits on Oct 17, 2019
  1. [bcl] Remove CompareExchange_T (#17370)

    lambdageek committed Oct 17, 2019
    In #17341 we change the caller of
    CompareExchange_T<T>(ref T, ...) to call CompareExchange (ref object, ...), but
    didn't delete the declaration.
    It's already deleted in unmanaged and in the netcore version of this file.
Commits on Oct 16, 2019
  1. [bcl][jit] implement Interlocked.Exchange<T> in terms of object (#17341)

    lambdageek committed Oct 16, 2019
    * [bcl][jit] implement Interlocked.Exchange<T> in terms of object
    Exchange<T> is supposed to be picked up as an intrinsic.  But if it isn't,
    since T has a class constraint, call the `Exchange (ref object, ref object, ref
    object)` overload instead.
    This works around a limitation in the JIT:
    if we're in the common call trampoline, and the caller is generic method and
    the callee is a generic method, if we're using generic sharing for the caller,
    but there's no generic jit info for the callee, we will not patch the call
    In this case we had Exchange<T> calling Exchange_T<T>
    where the callee is an icall (and evidently didn't have generic jit info).
    So every time we called Exchange<T>, we would go through the trampoline when
    trying to call Exchange_T<T> without patching the call site.
    Addresses part of #17334
    * Bump Mono
    * Also drop CompareExchange_T<T>
    * Sprinkle some Unsafe magic.
    Mark the non-icall methods that we expect the JIT to treet as intrinsics with [Intrinsic]
    * aot-runtime doesn't need Volatile.Read<T>/Write<T> code
    Both of those methods are implemented as calls to the object overload of Volatile.Read/Write
Commits on Oct 11, 2019
  1. [sdks] Android runner: properly shutdown runtime for Mono.Debugger.So…

    lambdageek committed Oct 11, 2019
    …ft test app (#17261)
    * [sdks] properly shutdown runtime for Mono.Debugger.Soft test app
    mini_jit_cleanup will cause mono_runtime_try_shutdown to be called before
    mono_runtime_quit which will set the shutting down flags in the runtime.
    * [test] Re-enable disabled tests
Commits on Oct 5, 2019
  1. [merp] Put thread into async context before running summarizer (#17194)

    lambdageek committed Oct 5, 2019
    Followup work for #17090
    In order to get managed method info for unmanaged stacktraces, we call
    mini_jit_info_table_find_ext which calls decode_exception_debug_info which may
    allocate if it's not in async context.
    Do the switch in mono_threads_summarize_execute so that non-supervising threads
    all switch when they run the sigterm_signal_handler.  mono_threads_summarize
    already does it for the supervisor thread.
    Fixes #17180
  2. [merp] exit_status is 0 if we ran the uploader successfully (#17185)

    lambdageek committed Oct 5, 2019
    Not 1 (TRUE)
Commits on Oct 4, 2019
  1. [merp] Don't overrun buffer in copy_summary_string_safe … (#17176)

    lambdageek authored and alexischr committed Oct 4, 2019
    * [merp] Don't overrun buffer in copy_summary_string_safe
    MonoFrameSummary:str_destr is an array of MONO_MAX_SUMMARY_NAME_LEN bytes, not
    Fixes Coverity CID 1454563
    * [merp] Use g_strlcpy for copy_summary_string_safe
    Fixes Coverity CID 1454563
    We would sometimes write to MonoSummaryFrame:str_descr which is
    is one past the end of the array.
    * nit: rename confusing parameter names
    old names were confusing - we were copying from 'out' to 'in'.  Now we copy to
    'dest' from 'src'
Commits on Sep 26, 2019
  1. [runtime] Respect runtime_version in mono_init_internal (#17085)

    lambdageek committed Sep 26, 2019
    In 6d2c77f we changed the representation of
    the runtimes that we will probe from a NULL-terminated array to a linked list.
    Unfortunately we made a typo, and in the case where the caller of
    mono_init_internal provided a runtime_version, we still picked
    DEFAULT_RUNTIME_VERSION instead of the given runtime_version.
    This is an issue for embedders like XA that use the "mobile" runtime - all
    their assemblies are compiled with the "mobile" version number ( but
    Mono running with the default runtime configuration will remap to  As
    a result, when there are references to assemblies, the load requests
    will be remapped to which will never see the already loaded
    assemblies, and we will fall back on the embedder's preload hook or filesystem
    probing every single time.  This is a performance fail.
Commits on Sep 20, 2019
  1. [System] Make FileSystemWatcher backend non-static (#16922)

    lambdageek authored and steveisok committed Sep 20, 2019
    * [System] Make FileSystemWatcher backend non-static
    The FileSystemWatcher `watcher` field is the backend IFileWatcher that's
    supposed to be used for the actual operations.
    Each backend has a `bool GetInstance (out watcher)` method that returns a
    singleton object, so each new instance of FileSystemWatcher gets the same
    IFileWatcher instance.  (They will get different `watcher_handle` instances
    which are used by some backends to uniquely identify this FileSystemWatcher).
    However when the first FileSystemWatcher instance is `Dispose`d, it will set
    `watcher = null` which will prevent the remaining instances from calling
        watcher?.StopDispatching (watcher_handle);
        watcher?.Dispose (watcher_handle);
    which means that the backend won't properly cleanup resources for any other FSW
    instances that have other `watcher_handle` values.
    Addresses #16709
Commits on Aug 31, 2019
  1. [runtime] Make eglib tests run on CI (#16187)

    lambdageek authored and monojenkins committed Aug 31, 2019
    [runtime] Make eglib tests run on CI
    Update mono/eglib SUBDIRS to build tests after eglib is built.
    Add a check-local automake rule.
    Add CI steps to run the eglib tests.
Commits on Aug 28, 2019
  1. [merp] Initialize hang_watchdog_path earlier; be lax if it's missing (#…

    lambdageek committed Aug 28, 2019
    * [merp] Initialize hang_watchdog_path earlier; be lax if it's missing
    Initialize hang_watchdog_path earlier - not just when
    ves_icall_Mono_Runtime_EnableCrashReportingLog is called.  That function is
    only expected to be called by apps that explicitly want progress reports from
    MERP when it's collecting a crash report.  But we want the mono-hang-watchdog
    to execute for all mono crashes (when crash reporting isn't ifdef'd out).
    Also if we try to exec mono-hang-watchdog and fail for some reason, print a
    nice message and then exit.  We used to call g_assert_not_reached which would
    kick off another MERP of the _forked child process_ which would then get
    confused because it really can't run in the forked process at all.
Commits on Aug 26, 2019
  1. [threadpool-io] Throw if backend won't be able to register a FD (#16396)

    lambdageek committed Aug 26, 2019
    The poll+select i/o selector backend can't handle file descriptor ids greater
    than FD_SETSIZE.  This can happen if too many files are open and we want to
    wait on it.
    Previously, mono would fail in the i/o selector thread by which point it was
    too late to do anything.
    With this change we will fail eagerly on the thread that calls IOSelector.Add
    by throwing a NotSupportedException.
    Addresses #15931
Commits on Aug 22, 2019
  1. [android] mono_dl_open_file: use g_file_test only on absolute paths (#…

    lambdageek committed Aug 22, 2019
    The intention of calling `g_file_test (file, G_FILE_TEST_EXISTS)` where file is
    the name of a shared library we want to open is to speed up probing for
    non-existent libraries.
    See #12074
    The problem is that if file is just a simple "" then `dlopen (file)`
    doesn't just look for it in the current working directory, it will probe some
    other paths too.  (For example on desktop linux you'd also look in all the
    directories in LD_LIBRARY_PATH).  So the g_file_test() call is not a robust way
    to avoid calling dlopen if the filename is relative.
    But it actually broke more things: xamarin/xamarin-android#3388
    When probing for "" on Android mono_lookup_pinvoke_call will first try
    prepending some paths that it knows about and we end up calling
    `dlopen ("/system/lib/")` which will fail because Bionic has security
    restrictions on what code can dlopen something from /system/lib with an
    absolute path.  Eventually mono_lookup_pinvoke_call will go back to trying the
    bare "" which hits `g_file_test` and returns NULL.
    The new code only does the file test if we pass it an absolute path, which
    gives Bionic's dlopen a chance to deal with relative paths however it needs to.
Commits on Aug 20, 2019
  1. [w32socket] Translate some errno codes to WSA_ errors imprecisely.

    lambdageek committed Aug 19, 2019
    These aren't a perfect match, but better than falling into the `default` case
    where Mono asserts and crashes.
    Addresses part of #16024
Commits on Aug 19, 2019
  1. [coop] Add a handle frame in construct_culture (#16299)

    lambdageek committed Aug 19, 2019
    Otherwise we see warnings like these:
    ves_icall_System_Globalization_CultureInfo_internal_get_cultures_raw USED 680 handles
You can’t perform that action at this time.