From cc5971f5bd3d2daa8973d05d33e824aa29fbb3bd Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Mon, 9 Jan 2023 06:09:22 -0800 Subject: [PATCH 01/32] CoreCLR shim files renamed to AOT --- .../nativeaot/Runtime/eventpipe/ds-rt-aot.h | 363 ++ .../Runtime/eventpipe/ds-rt-types-aot.h | 40 + .../nativeaot/Runtime/eventpipe/ep-rt-aot.cpp | 164 + .../nativeaot/Runtime/eventpipe/ep-rt-aot.h | 3160 +++++++++++++++++ .../Runtime/eventpipe/ep-rt-config-aot.h | 4 + .../Runtime/eventpipe/ep-rt-types-aot.h | 340 ++ 6 files changed, 4071 insertions(+) create mode 100644 src/coreclr/nativeaot/Runtime/eventpipe/ds-rt-aot.h create mode 100644 src/coreclr/nativeaot/Runtime/eventpipe/ds-rt-types-aot.h create mode 100644 src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp create mode 100644 src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h create mode 100644 src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-config-aot.h create mode 100644 src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ds-rt-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ds-rt-aot.h new file mode 100644 index 0000000000000..2742a21684710 --- /dev/null +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ds-rt-aot.h @@ -0,0 +1,363 @@ +// Implementation of ds-rt.h targeting Mono runtime. +#ifndef __DIAGNOSTICS_RT_MONO_H__ +#define __DIAGNOSTICS_RT_MONO_H__ + +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-coreclr.h" +#include +#include +#include +#include + +#undef DS_LOG_ALWAYS_0 +#define DS_LOG_ALWAYS_0(msg) STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_ALWAYS, msg "\n") + +#undef DS_LOG_ALWAYS_1 +#define DS_LOG_ALWAYS_1(msg, data1) STRESS_LOG1(LF_DIAGNOSTICS_PORT, LL_ALWAYS, msg "\n", data1) + +#undef DS_LOG_ALWAYS_2 +#define DS_LOG_ALWAYS_2(msg, data1, data2) STRESS_LOG2(LF_DIAGNOSTICS_PORT, LL_ALWAYS, msg "\n", data1, data2) + +#undef DS_LOG_INFO_0 +#define DS_LOG_INFO_0(msg) STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_INFO10, msg "\n") + +#undef DS_LOG_INFO_1 +#define DS_LOG_INFO_1(msg, data1) STRESS_LOG1(LF_DIAGNOSTICS_PORT, LL_INFO10, msg "\n", data1) + +#undef DS_LOG_INFO_2 +#define DS_LOG_INFO_2(msg, data1, data2) STRESS_LOG2(LF_DIAGNOSTICS_PORT, LL_INFO10, msg "\n", data1, data2) + +#undef DS_LOG_ERROR_0 +#define DS_LOG_ERROR_0(msg) STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_ERROR, msg "\n") + +#undef DS_LOG_ERROR_1 +#define DS_LOG_ERROR_1(msg, data1) STRESS_LOG1(LF_DIAGNOSTICS_PORT, LL_ERROR, msg "\n", data1) + +#undef DS_LOG_ERROR_2 +#define DS_LOG_ERROR_2(msg, data1, data2) STRESS_LOG2(LF_DIAGNOSTICS_PORT, LL_ERROR, msg "\n", data1, data2) + +#undef DS_LOG_WARNING_0 +#define DS_LOG_WARNING_0(msg) STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_WARNING, msg "\n") + +#undef DS_LOG_WARNING_1 +#define DS_LOG_WARNING_1(msg, data1) STRESS_LOG1(LF_DIAGNOSTICS_PORT, LL_WARNING, msg "\n", data1) + +#undef DS_LOG_WARNING_2 +#define DS_LOG_WARNING_2(msg, data1, data2) STRESS_LOG2(LF_DIAGNOSTICS_PORT, LL_WARNING, msg "\n", data1, data2) + +#undef DS_LOG_DEBUG_0 +#define DS_LOG_DEBUG_0(msg) STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_INFO1000, msg "\n") + +#undef DS_LOG_DEBUG_1 +#define DS_LOG_DEBUG_1(msg, data1) STRESS_LOG1(LF_DIAGNOSTICS_PORT, LL_INFO1000, msg "\n", data1) + +#undef DS_LOG_DEBUG_2 +#define DS_LOG_DEBUG_2(msg, data1, data2) STRESS_LOG2(LF_DIAGNOSTICS_PORT, LL_INFO1000, msg "\n", data1, data2) + +#undef DS_ENTER_BLOCKING_PAL_SECTION +#define DS_ENTER_BLOCKING_PAL_SECTION + +#undef DS_EXIT_BLOCKING_PAL_SECTION +#define DS_EXIT_BLOCKING_PAL_SECTION + +#undef DS_RT_DEFINE_ARRAY +#define DS_RT_DEFINE_ARRAY(array_name, array_type, iterator_type, item_type) \ + EP_RT_DEFINE_ARRAY_PREFIX(ds, array_name, array_type, iterator_type, item_type) + +#undef DS_RT_DEFINE_LOCAL_ARRAY +#define DS_RT_DEFINE_LOCAL_ARRAY(array_name, array_type, iterator_type, item_type) \ + EP_RT_DEFINE_LOCAL_ARRAY_PREFIX(ds, array_name, array_type, iterator_type, item_type) + +#undef DS_RT_DEFINE_ARRAY_ITERATOR +#define DS_RT_DEFINE_ARRAY_ITERATOR(array_name, array_type, iterator_type, item_type) \ + EP_RT_DEFINE_ARRAY_ITERATOR_PREFIX(ds, array_name, array_type, iterator_type, item_type) + +#undef DS_RT_DEFINE_ARRAY_REVERSE_ITERATOR +#define DS_RT_DEFINE_ARRAY_REVERSE_ITERATOR(array_name, array_type, iterator_type, item_type) \ + EP_RT_DEFINE_ARRAY_REVERSE_ITERATOR_PREFIX(ds, array_name, array_type, iterator_type, item_type) + +/* +* AutoTrace. +*/ + +#ifdef FEATURE_AUTO_TRACE +#include "autotrace.h" +#endif + +static +void +ds_rt_auto_trace_init (void) +{ + STATIC_CONTRACT_NOTHROW; + +#ifdef FEATURE_AUTO_TRACE + EX_TRY + { + auto_trace_init (); + } + EX_CATCH {} + EX_END_CATCH(SwallowAllExceptions); +#endif +} + +static +void +ds_rt_auto_trace_launch (void) +{ + STATIC_CONTRACT_NOTHROW; + +#ifdef FEATURE_AUTO_TRACE + EX_TRY + { + auto_trace_launch (); + } + EX_CATCH {} + EX_END_CATCH(SwallowAllExceptions); +#endif +} + +static +void +ds_rt_auto_trace_signal (void) +{ + STATIC_CONTRACT_NOTHROW; + +#ifdef FEATURE_AUTO_TRACE + EX_TRY + { + auto_trace_signal (); + } + EX_CATCH {} + EX_END_CATCH(SwallowAllExceptions); +#endif +} + +static +void +ds_rt_auto_trace_wait (void) +{ + STATIC_CONTRACT_NOTHROW; + +#ifdef FEATURE_AUTO_TRACE + EX_TRY + { + auto_trace_wait (); + } + EX_CATCH {} + EX_END_CATCH(SwallowAllExceptions); +#endif +} + +/* + * DiagnosticsConfiguration. + */ + +static +inline +bool +ds_rt_config_value_get_enable (void) +{ + STATIC_CONTRACT_NOTHROW; + return CLRConfig::GetConfigValue (CLRConfig::EXTERNAL_EnableDiagnostics) != 0; +} + +static +inline +ep_char8_t * +ds_rt_config_value_get_ports (void) +{ + STATIC_CONTRACT_NOTHROW; + + CLRConfigStringHolder value(CLRConfig::GetConfigValue (CLRConfig::EXTERNAL_DOTNET_DiagnosticPorts)); + return ep_rt_utf16_to_utf8_string (reinterpret_cast(value.GetValue ()), -1); +} + +static +inline +uint32_t +ds_rt_config_value_get_default_port_suspend (void) +{ + STATIC_CONTRACT_NOTHROW; + return static_cast(CLRConfig::GetConfigValue (CLRConfig::EXTERNAL_DOTNET_DefaultDiagnosticPortSuspend)); +} + +/* +* DiagnosticsDump. +*/ + +static +ds_ipc_result_t +ds_rt_generate_core_dump ( + DiagnosticsDumpCommandId commandId, + DiagnosticsGenerateCoreDumpCommandPayload *payload, + ep_char8_t *errorMessageBuffer, + int32_t cbErrorMessageBuffer) +{ + STATIC_CONTRACT_NOTHROW; + + ds_ipc_result_t result = DS_IPC_E_FAIL; + EX_TRY + { + uint32_t flags = ds_generate_core_dump_command_payload_get_flags(payload); + if (commandId == DS_DUMP_COMMANDID_GENERATE_CORE_DUMP) + { + // For the old commmand, this payload field is a bool of whether to enable logging + flags = flags != 0 ? GenerateDumpFlagsLoggingEnabled : 0; + } + LPCWSTR dumpName = reinterpret_cast(ds_generate_core_dump_command_payload_get_dump_name (payload)); + int32_t dumpType = static_cast(ds_generate_core_dump_command_payload_get_dump_type (payload)); + if (GenerateDump(dumpName, dumpType, flags, errorMessageBuffer, cbErrorMessageBuffer)) + { + result = DS_IPC_S_OK; + } + } + EX_CATCH {} + EX_END_CATCH(SwallowAllExceptions); + return result; +} + +/* + * DiagnosticsIpc. + */ + +static +inline +bool +ds_rt_transport_get_default_name ( + ep_char8_t *name, + int32_t name_len, + const ep_char8_t *prefix, + int32_t id, + const ep_char8_t *group_id, + const ep_char8_t *suffix) +{ + STATIC_CONTRACT_NOTHROW; + +#ifdef TARGET_UNIX + PAL_GetTransportName (name_len, name, prefix, id, group_id, suffix); +#endif + return true; +} + +/* + * DiagnosticsIpcPollHandle. + */ + +DS_RT_DEFINE_ARRAY (ipc_poll_handle_array, ds_rt_ipc_poll_handle_array_t, ds_rt_ipc_poll_handle_array_iterator_t, DiagnosticsIpcPollHandle) +DS_RT_DEFINE_LOCAL_ARRAY (ipc_poll_handle_array, ds_rt_ipc_poll_handle_array_t, ds_rt_ipc_poll_handle_array_iterator_t, DiagnosticsIpcPollHandle) +DS_RT_DEFINE_ARRAY_ITERATOR (ipc_poll_handle_array, ds_rt_ipc_poll_handle_array_t, ds_rt_ipc_poll_handle_array_iterator_t, DiagnosticsIpcPollHandle) + +#undef DS_RT_DECLARE_LOCAL_IPC_POLL_HANDLE_ARRAY +#define DS_RT_DECLARE_LOCAL_IPC_POLL_HANDLE_ARRAY(var_name) \ + EP_RT_DECLARE_LOCAL_ARRAY_VARIABLE(var_name, ds_rt_ipc_poll_handle_array_t) + +/* + * DiagnosticsPort. + */ + +DS_RT_DEFINE_ARRAY (port_array, ds_rt_port_array_t, ds_rt_port_array_iterator_t, DiagnosticsPort *) +DS_RT_DEFINE_ARRAY_ITERATOR (port_array, ds_rt_port_array_t, ds_rt_port_array_iterator_t, DiagnosticsPort *) + +DS_RT_DEFINE_ARRAY (port_config_array, ds_rt_port_config_array_t, ds_rt_port_config_array_iterator_t, ep_char8_t *) +DS_RT_DEFINE_LOCAL_ARRAY (port_config_array, ds_rt_port_config_array_t, ds_rt_port_config_array_iterator_t, ep_char8_t *) +DS_RT_DEFINE_ARRAY_ITERATOR (port_config_array, ds_rt_port_config_array_t, ds_rt_port_config_array_iterator_t, ep_char8_t *) +DS_RT_DEFINE_ARRAY_REVERSE_ITERATOR (port_config_array, ds_rt_port_config_array_t, ds_rt_port_config_array_reverse_iterator_t, ep_char8_t *) + +#undef DS_RT_DECLARE_LOCAL_PORT_CONFIG_ARRAY +#define DS_RT_DECLARE_LOCAL_PORT_CONFIG_ARRAY(var_name) \ + EP_RT_DECLARE_LOCAL_ARRAY_VARIABLE(var_name, ds_rt_port_config_array_t) + +/* +* DiagnosticsProfiler. +*/ +#ifdef PROFILING_SUPPORTED +#include "profilinghelper.h" +#include "profilinghelper.inl" + +#ifdef FEATURE_PROFAPI_ATTACH_DETACH +static +uint32_t +ds_rt_profiler_attach (DiagnosticsAttachProfilerCommandPayload *payload) +{ + STATIC_CONTRACT_NOTHROW; + + if (!g_profControlBlock.fProfControlBlockInitialized) + return DS_IPC_E_RUNTIME_UNINITIALIZED; + + // Certain actions are only allowable during attach, and this flag is how we track it. + ClrFlsSetThreadType (ThreadType_ProfAPI_Attach); + + HRESULT hr = S_OK; + EX_TRY { + hr = ProfilingAPIUtility::LoadProfilerForAttach (reinterpret_cast(ds_attach_profiler_command_payload_get_profiler_guid_cref (payload)), + reinterpret_cast(ds_attach_profiler_command_payload_get_profiler_path (payload)), + reinterpret_cast(ds_attach_profiler_command_payload_get_client_data (payload)), + static_cast(ds_attach_profiler_command_payload_get_client_data_len (payload)), + static_cast(ds_attach_profiler_command_payload_get_attach_timeout (payload))); + } + EX_CATCH_HRESULT (hr); + + // Clear the flag so this thread isn't permanently marked as the attach thread. + ClrFlsClearThreadType (ThreadType_ProfAPI_Attach); + + return hr; +} +#endif // FEATURE_PROFAPI_ATTACH_DETACH + +static +uint32_t +ds_rt_profiler_startup (DiagnosticsStartupProfilerCommandPayload *payload) +{ + STATIC_CONTRACT_NOTHROW; + + HRESULT hr = S_OK; + EX_TRY { + StoredProfilerNode *profilerData = new StoredProfilerNode(); + profilerData->guid = *(reinterpret_cast(ds_startup_profiler_command_payload_get_profiler_guid_cref (payload))); + profilerData->path.Set(reinterpret_cast(ds_startup_profiler_command_payload_get_profiler_path (payload))); + + g_profControlBlock.storedProfilers.InsertHead(profilerData); + } + EX_CATCH_HRESULT (hr); + + return hr; +} +#endif // PROFILING_SUPPORTED + +static +uint32_t +ds_rt_set_environment_variable (const ep_char16_t *name, const ep_char16_t *value) +{ + return SetEnvironmentVariableW(reinterpret_cast(name), reinterpret_cast(value)) ? S_OK : HRESULT_FROM_WIN32(GetLastError()); +} + +/* +* DiagnosticServer. +*/ + +static +void +ds_rt_server_log_pause_message (void) +{ + STATIC_CONTRACT_NOTHROW; + + const char diagPortsName[] = "DOTNET_DiagnosticPorts"; + CLRConfigNoCache diagPorts = CLRConfigNoCache::Get(diagPortsName); + LPCSTR ports = nullptr; + if (diagPorts.IsSet()) + { + ports = diagPorts.AsString(); + } + + uint32_t port_suspended = ds_rt_config_value_get_default_port_suspend(); + + printf("The runtime has been configured to pause during startup and is awaiting a Diagnostics IPC ResumeStartup command from a Diagnostic Port.\n"); + printf("%s=\"%s\"\n", diagPortsName, ports == nullptr ? "" : ports); + printf("DOTNET_DefaultDiagnosticPortSuspend=%u\n", port_suspended); + fflush(stdout); +} + +#endif /* ENABLE_PERFTRACING */ +#endif /* __DIAGNOSTICS_RT_MONO_H__ */ diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ds-rt-types-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ds-rt-types-aot.h new file mode 100644 index 0000000000000..529590fb22cbc --- /dev/null +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ds-rt-types-aot.h @@ -0,0 +1,40 @@ +// Implementation of ds-rt-types.h targeting CoreCLR runtime. +#ifndef __DIAGNOSTICS_RT_TYPES_CORECLR_H__ +#define __DIAGNOSTICS_RT_TYPES_CORECLR_H__ + +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-types-coreclr.h" + +/* + * DiagnosticsIpcPollHandle. + */ + +#undef ds_rt_ipc_poll_handle_array_t +typedef struct _rt_coreclr_array_internal_t ds_rt_ipc_poll_handle_array_t; + +#undef ds_rt_ipc_poll_handle_array_iterator_t +typedef struct _rt_coreclr_array_iterator_internal_t ds_rt_ipc_poll_handle_array_iterator_t; + +/* + * DiagnosticsPort. + */ + +#undef ds_rt_port_array_t +typedef struct _rt_coreclr_array_internal_t ds_rt_port_array_t; + +#undef ds_rt_port_array_iterator_t +typedef struct _rt_coreclr_array_iterator_internal_t ds_rt_port_array_iterator_t; + +#undef ds_rt_port_config_array_t +typedef struct _rt_coreclr_array_internal_t ds_rt_port_config_array_t; + +#undef ds_rt_port_config_array_iterator_t +typedef struct _rt_coreclr_array_iterator_internal_t ds_rt_port_config_array_iterator_t; + +#undef ds_rt_port_config_array_reverse_iterator_t +typedef struct _rt_coreclr_array_iterator_internal_t ds_rt_port_config_array_reverse_iterator_t; + +#endif /* ENABLE_PERFTRACING */ +#endif /* __DIAGNOSTICS_RT_TYPES_CORECLR_H__ */ diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp new file mode 100644 index 0000000000000..18aa5126930c7 --- /dev/null +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp @@ -0,0 +1,164 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include +#include +#include +#include +#include "threadsuspend.h" + +ep_rt_lock_handle_t _ep_rt_coreclr_config_lock_handle; +CrstStatic _ep_rt_coreclr_config_lock; + +thread_local EventPipeCoreCLRThreadHolderTLS EventPipeCoreCLRThreadHolderTLS::g_threadHolderTLS; + +ep_char8_t *volatile _ep_rt_coreclr_diagnostics_cmd_line; + +#ifndef TARGET_UNIX +uint32_t *_ep_rt_coreclr_proc_group_offsets; +#endif + +/* + * Forward declares of all static functions. + */ + +static +StackWalkAction +stack_walk_callback ( + CrawlFrame *frame, + EventPipeStackContents *stack_contents); + +static +void +walk_managed_stack_for_threads ( + ep_rt_thread_handle_t sampling_thread, + EventPipeEvent *sampling_event); + +static +StackWalkAction +stack_walk_callback ( + CrawlFrame *frame, + EventPipeStackContents *stack_contents) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (frame != NULL); + EP_ASSERT (stack_contents != NULL); + + // Get the IP. + UINT_PTR control_pc = (UINT_PTR)frame->GetRegisterSet ()->ControlPC; + if (control_pc == NULL) { + if (ep_stack_contents_get_length (stack_contents) == 0) { + // This happens for pinvoke stubs on the top of the stack. + return SWA_CONTINUE; + } + } + + EP_ASSERT (control_pc != NULL); + + // Add the IP to the captured stack. + ep_stack_contents_append (stack_contents, control_pc, frame->GetFunction ()); + + // Continue the stack walk. + return SWA_CONTINUE; +} + +bool +ep_rt_coreclr_walk_managed_stack_for_thread ( + ep_rt_thread_handle_t thread, + EventPipeStackContents *stack_contents) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (thread != NULL); + EP_ASSERT (stack_contents != NULL); + + // Calling into StackWalkFrames in preemptive mode violates the host contract, + // but this contract is not used on CoreCLR. + CONTRACT_VIOLATION (HostViolation); + + // Before we call into StackWalkFrames we need to mark GC_ON_TRANSITIONS as FALSE + // because under GCStress runs (GCStress=0x3), a GC will be triggered for every transition, + // which will cause the GC to try to walk the stack while we are in the middle of walking the stack. + bool gc_on_transitions = GC_ON_TRANSITIONS (FALSE); + + StackWalkAction result = thread->StackWalkFrames ( + (PSTACKWALKFRAMESCALLBACK)stack_walk_callback, + stack_contents, + ALLOW_ASYNC_STACK_WALK | FUNCTIONSONLY | HANDLESKIPPEDFRAMES | ALLOW_INVALID_OBJECTS); + + GC_ON_TRANSITIONS (gc_on_transitions); + return ((result == SWA_DONE) || (result == SWA_CONTINUE)); +} + +// The thread store lock must already be held by the thread before this function +// is called. ThreadSuspend::SuspendEE acquires the thread store lock. +static +void +walk_managed_stack_for_threads ( + ep_rt_thread_handle_t sampling_thread, + EventPipeEvent *sampling_event) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (sampling_thread != NULL); + + Thread *target_thread = NULL; + + EventPipeStackContents stack_contents; + EventPipeStackContents *current_stack_contents; + current_stack_contents = ep_stack_contents_init (&stack_contents); + + EP_ASSERT (current_stack_contents != NULL); + + // Iterate over all managed threads. + // Assumes that the ThreadStoreLock is held because we've suspended all threads. + while ((target_thread = ThreadStore::GetThreadList (target_thread)) != NULL) { + ep_stack_contents_reset (current_stack_contents); + + // Walk the stack and write it out as an event. + if (ep_rt_coreclr_walk_managed_stack_for_thread (target_thread, current_stack_contents) && !ep_stack_contents_is_empty (current_stack_contents)) { + // Set the payload. If the GC mode on suspension > 0, then the thread was in cooperative mode. + // Even though there are some cases where this is not managed code, we assume it is managed code here. + // If the GC mode on suspension == 0 then the thread was in preemptive mode, which we qualify as external here. + uint32_t payload_data = target_thread->GetGCModeOnSuspension () ? EP_SAMPLE_PROFILER_SAMPLE_TYPE_MANAGED : EP_SAMPLE_PROFILER_SAMPLE_TYPE_EXTERNAL; + + // Write the sample. + ep_write_sample_profile_event ( + sampling_thread, + sampling_event, + target_thread, + current_stack_contents, + (uint8_t *)&payload_data, + sizeof (payload_data)); + } + + // Reset the GC mode. + target_thread->ClearGCModeOnSuspension (); + } + + ep_stack_contents_fini (current_stack_contents); +} + +void +ep_rt_coreclr_sample_profiler_write_sampling_event_for_threads ( + ep_rt_thread_handle_t sampling_thread, + EventPipeEvent *sampling_event) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (sampling_thread != NULL); + + // Check to see if we can suspend managed execution. + if (ThreadSuspend::SysIsSuspendInProgress () || (ThreadSuspend::GetSuspensionThread () != 0)) + return; + + // Actually suspend managed execution. + ThreadSuspend::SuspendEE (ThreadSuspend::SUSPEND_REASON::SUSPEND_OTHER); + + // Walk all managed threads and capture stacks. + walk_managed_stack_for_threads (sampling_thread, sampling_event); + + // Resume managed execution. + ThreadSuspend::RestartEE (FALSE /* bFinishedGC */, TRUE /* SuspendSucceeded */); + + return; +} + +#endif /* ENABLE_PERFTRACING */ diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h new file mode 100644 index 0000000000000..482626b51313c --- /dev/null +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h @@ -0,0 +1,3160 @@ +// Implementation of ep-rt.h targeting CoreCLR runtime. +#ifndef __EVENTPIPE_RT_CORECLR_H__ +#define __EVENTPIPE_RT_CORECLR_H__ + +#include + +#ifdef ENABLE_PERFTRACING +#include +#include +#include +#include +#include "fstream.h" +#include "typestring.h" +#include "clrversion.h" + +#undef EP_INFINITE_WAIT +#define EP_INFINITE_WAIT INFINITE + +#undef EP_GCX_PREEMP_ENTER +#define EP_GCX_PREEMP_ENTER { GCX_PREEMP(); + +#undef EP_GCX_PREEMP_EXIT +#define EP_GCX_PREEMP_EXIT } + +#undef EP_ALWAYS_INLINE +#define EP_ALWAYS_INLINE FORCEINLINE + +#undef EP_NEVER_INLINE +#define EP_NEVER_INLINE NOINLINE + +#undef EP_ALIGN_UP +#define EP_ALIGN_UP(val,align) ALIGN_UP(val,align) + +#ifndef EP_RT_BUILD_TYPE_FUNC_NAME +#define EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, type_name, func_name) \ +prefix_name ## _rt_ ## type_name ## _ ## func_name +#endif + +template +static +inline +void +_rt_coreclr_list_alloc (LIST_TYPE *list) { + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (list != NULL); + + list->list = new (nothrow) typename LIST_TYPE::list_type_t (); +} + +template +static +inline +void +_rt_coreclr_list_free ( + LIST_TYPE *list, + void (*callback)(void *)) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (list != NULL); + + if (list->list) { + while (!list->list->IsEmpty ()) { + typename LIST_TYPE::element_type_t *current = list->list->RemoveHead (); + if (callback) + callback (reinterpret_cast(current->GetValue ())); + delete current; + } + delete list->list; + } + list->list = NULL; +} + +template +static +inline +void +_rt_coreclr_list_clear ( + LIST_TYPE *list, + void (*callback)(void *)) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (list != NULL && list->list != NULL); + + while (!list->list->IsEmpty ()) { + typename LIST_TYPE::element_type_t *current = list->list->RemoveHead (); + if (callback) + callback (reinterpret_cast(current->GetValue ())); + delete current; + } +} + +template +static +inline +bool +_rt_coreclr_list_append ( + LIST_TYPE *list, + LIST_ITEM item) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (list != NULL && list->list != NULL); + + typename LIST_TYPE::element_type_t *node = new (nothrow) typename LIST_TYPE::element_type_t (item); + if (node) + list->list->InsertTail (node); + return (node != NULL); +} + +template +static +inline +void +_rt_coreclr_list_remove ( + LIST_TYPE *list, + CONST_LIST_ITEM item) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (list != NULL && list->list != NULL); + + typename LIST_TYPE::element_type_t *current = list->list->GetHead (); + while (current) { + if (current->GetValue () == item) { + if (list->list->FindAndRemove (current)) + delete current; + break; + } + current = list->list->GetNext (current); + } +} + +template +static +inline +bool +_rt_coreclr_list_find ( + CONST_LIST_TYPE *list, + CONST_LIST_ITEM item_to_find, + LIST_ITEM *found_item) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (list != NULL && list->list != NULL); + EP_ASSERT (found_item != NULL); + + bool found = false; + typename LIST_TYPE::element_type_t *current = list->list->GetHead (); + while (current) { + if (current->GetValue () == item_to_find) { + *found_item = current->GetValue (); + found = true; + break; + } + current = list->list->GetNext (current); + } + return found; +} + +template +static +inline +bool +_rt_coreclr_list_is_empty (CONST_LIST_TYPE *list) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (list != NULL); + + return (list->list == NULL || list->list->IsEmpty ()); +} + +template +static +inline +bool +_rt_coreclr_list_is_valid (CONST_LIST_TYPE *list) +{ + STATIC_CONTRACT_NOTHROW; + return (list != NULL && list->list != NULL); +} + +template +static +inline +ITERATOR_TYPE +_rt_coreclr_list_iterator_begin (CONST_LIST_TYPE *list) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (list != NULL && list->list != NULL); + + return list->list->begin (); +} + +template +static +inline +bool +_rt_coreclr_list_iterator_end ( + CONST_LIST_TYPE *list, + CONST_ITERATOR_TYPE *iterator) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (list != NULL && list->list != NULL && iterator != NULL); + + return (*iterator == list->list->end ()); +} + +template +static +inline +void +_rt_coreclr_list_iterator_next (ITERATOR_TYPE *iterator) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (iterator != NULL); + + (*iterator)++; +} + +template +static +inline +ITEM_TYPE +_rt_coreclr_list_iterator_value (CONST_ITERATOR_TYPE *iterator) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (iterator != NULL); + + return const_cast(iterator)->operator*(); +} + +template +static +inline +void +_rt_coreclr_queue_alloc (QUEUE_TYPE *queue) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (queue != NULL); + + queue->queue = new (nothrow) typename QUEUE_TYPE::queue_type_t (); +} + +template +static +inline +void +_rt_coreclr_queue_free (QUEUE_TYPE *queue) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (queue != NULL); + + if (queue->queue) + delete queue->queue; + queue->queue = NULL; +} + +template +static +inline +bool +_rt_coreclr_queue_pop_head ( + QUEUE_TYPE *queue, + ITEM_TYPE *item) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (queue != NULL && queue->queue != NULL && item != NULL); + + bool found = true; + typename QUEUE_TYPE::element_type_t *node = queue->queue->RemoveHead (); + if (node) { + *item = node->m_Value; + delete node; + } else { + *item = NULL; + found = false; + } + return found; +} + +template +static +inline +bool +_rt_coreclr_queue_push_head ( + QUEUE_TYPE *queue, + ITEM_TYPE item) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (queue != NULL && queue->queue != NULL); + + typename QUEUE_TYPE::element_type_t *node = new (nothrow) typename QUEUE_TYPE::element_type_t (item); + if (node) + queue->queue->InsertHead (node); + return (node != NULL); +} + +template +static +inline +bool +_rt_coreclr_queue_push_tail ( + QUEUE_TYPE *queue, + ITEM_TYPE item) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (queue != NULL && queue->queue != NULL); + + typename QUEUE_TYPE::element_type_t *node = new (nothrow) typename QUEUE_TYPE::element_type_t (item); + if (node) + queue->queue->InsertTail (node); + return (node != NULL); +} + +template +static +inline +bool +_rt_coreclr_queue_is_empty (CONST_QUEUE_TYPE *queue) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (queue != NULL && queue->queue != NULL); + + return (queue->queue != NULL && queue->queue->IsEmpty ()); +} + +template +static +inline +bool +_rt_coreclr_queue_is_valid (CONST_QUEUE_TYPE *queue) +{ + STATIC_CONTRACT_NOTHROW; + return (queue != NULL && queue->queue != NULL); +} + +template +static +inline +void +_rt_coreclr_array_alloc (ARRAY_TYPE *ep_array) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (ep_array != NULL); + + ep_array->array = new (nothrow) typename ARRAY_TYPE::array_type_t (); +} + +template +static +inline +void +_rt_coreclr_array_alloc_capacity ( + ARRAY_TYPE *ep_array, + size_t capacity) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (ep_array != NULL); + + ep_array->array = new (nothrow) typename ARRAY_TYPE::array_type_t (); + if (ep_array->array) + ep_array->array->AllocNoThrow (capacity); +} + +template +static +inline +void +_rt_coreclr_array_init_capacity ( + ARRAY_TYPE *ep_array, + size_t capacity) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (ep_array != NULL); + + if (ep_array->array) + ep_array->array->AllocNoThrow (capacity); +} + +template +static +inline +void +_rt_coreclr_array_free (ARRAY_TYPE *ep_array) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (ep_array != NULL); + + if (ep_array->array) { + delete ep_array->array; + ep_array->array = NULL; + } +} + +template +static +inline +bool +_rt_coreclr_array_append ( + ARRAY_TYPE *ep_array, + ITEM_TYPE item) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (ep_array != NULL && ep_array->array != NULL); + + return ep_array->array->PushNoThrow (item); +} + +template +static +inline +void +_rt_coreclr_array_clear (ARRAY_TYPE *ep_array) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (ep_array != NULL && ep_array->array != NULL); + + while (ep_array->array->Size () > 0) + ITEM_TYPE item = ep_array->array->Pop (); + ep_array->array->Shrink (); +} + +template +static +inline +size_t +_rt_coreclr_array_size (CONST_ARRAY_TYPE *ep_array) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (ep_array != NULL && ep_array->array != NULL); + + return ep_array->array->Size (); +} + +template +static +inline +ITEM_TYPE * +_rt_coreclr_array_data (CONST_ARRAY_TYPE *ep_array) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (ep_array != NULL && ep_array->array != NULL); + + return ep_array->array->Ptr (); +} + +template +static +inline +bool +_rt_coreclr_array_is_valid (CONST_ARRAY_TYPE *ep_array) +{ + STATIC_CONTRACT_NOTHROW; + return (ep_array->array != NULL); +} + +template +static +inline +ITERATOR_TYPE +_rt_coreclr_array_iterator_begin (CONST_ARRAY_TYPE *ep_array) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (ep_array != NULL && ep_array->array != NULL); + + ITERATOR_TYPE temp; + temp.array = ep_array->array; + temp.index = 0; + return temp; +} + +template +static +inline +bool +_rt_coreclr_array_iterator_end ( + CONST_ARRAY_TYPE *ep_array, + CONST_ITERATOR_TYPE *iterator) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (ep_array != NULL && iterator != NULL && iterator->array != NULL); + + return (iterator->index >= static_cast(iterator->array->Size ())); +} + +template +static +inline +void +_rt_coreclr_array_iterator_next (ITERATOR_TYPE *iterator) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (iterator != NULL); + + iterator->index++; +} + +template +static +inline +ITEM_TYPE +_rt_coreclr_array_iterator_value (const CONST_ITERATOR_TYPE *iterator) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (iterator != NULL && iterator->array != NULL); + EP_ASSERT (iterator->index < static_cast(iterator->array->Size ())); + + return iterator->array->operator[] (iterator->index); +} + +template +static +inline +ITERATOR_TYPE +_rt_coreclr_array_reverse_iterator_begin (CONST_ARRAY_TYPE *ep_array) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (ep_array != NULL && ep_array->array != NULL); + + ITERATOR_TYPE temp; + temp.array = ep_array->array; + temp.index = static_cast(ep_array->array->Size ()); + return temp; +} + +template +static +inline +bool +_rt_coreclr_array_reverse_iterator_end ( + CONST_ARRAY_TYPE *ep_array, + CONST_ITERATOR_TYPE *iterator) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (ep_array != NULL && iterator != NULL && iterator->array != NULL); + + return (iterator->index == 0); +} + +template +static +inline +void +_rt_coreclr_array_reverse_iterator_next (ITERATOR_TYPE *iterator) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (iterator != NULL); + + iterator->index--; +} + +template +static +inline +ITEM_TYPE +_rt_coreclr_array_reverse_iterator_value (CONST_ITERATOR_TYPE *iterator) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (iterator != NULL && iterator->array != NULL); + EP_ASSERT (iterator->index > 0); + + return iterator->array->operator[] (iterator->index - 1); +} + +template +static +inline +void +_rt_coreclr_hash_map_alloc ( + HASH_MAP_TYPE *hash_map, + uint32_t (*hash_callback)(const void *), + bool (*eq_callback)(const void *, const void *), + void (*key_free_callback)(void *), + void (*value_free_callback)(void *)) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (HASH_MAP_TYPE::table_type_t::s_NoThrow); + EP_ASSERT (hash_map != NULL && key_free_callback == NULL); + + hash_map->table = new (nothrow) typename HASH_MAP_TYPE::table_type_t (); + hash_map->callbacks.key_free_func = key_free_callback; + hash_map->callbacks.value_free_func = value_free_callback; +} + +template +static +inline +void +_rt_coreclr_hash_map_free (HASH_MAP_TYPE *hash_map) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (HASH_MAP_TYPE::table_type_t::s_NoThrow); + EP_ASSERT (hash_map != NULL); + + if (hash_map->table) { + if (hash_map->callbacks.value_free_func) { + for (typename HASH_MAP_TYPE::table_type_t::Iterator iterator = hash_map->table->Begin (); iterator != hash_map->table->End (); ++iterator) + hash_map->callbacks.value_free_func (reinterpret_cast((ptrdiff_t)(iterator->Value ()))); + } + delete hash_map->table; + } +} + +template +static +inline +bool +_rt_coreclr_hash_map_add ( + HASH_MAP_TYPE *hash_map, + KEY_TYPE key, + VALUE_TYPE value) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (HASH_MAP_TYPE::table_type_t::s_NoThrow); + EP_ASSERT (hash_map != NULL && hash_map->table != NULL); + + return hash_map->table->AddNoThrow (typename HASH_MAP_TYPE::table_type_t::element_t (key, value)); +} + +template +static +inline +bool +_rt_coreclr_hash_map_add_or_replace ( + HASH_MAP_TYPE *hash_map, + KEY_TYPE key, + VALUE_TYPE value) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (HASH_MAP_TYPE::table_type_t::s_NoThrow); + EP_ASSERT (hash_map != NULL && hash_map->table != NULL); + + return hash_map->table->AddOrReplaceNoThrow (typename HASH_MAP_TYPE::table_type_t::element_t (key, value)); +} + +template +static +inline +void +_rt_coreclr_hash_map_remove_all (HASH_MAP_TYPE *hash_map) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (HASH_MAP_TYPE::table_type_t::s_NoThrow); + EP_ASSERT (hash_map != NULL && hash_map->table != NULL); + + if (hash_map->callbacks.value_free_func) { + for (typename HASH_MAP_TYPE::table_type_t::Iterator iterator = hash_map->table->Begin (); iterator != hash_map->table->End (); ++iterator) + hash_map->callbacks.value_free_func (reinterpret_cast((ptrdiff_t)(iterator->Value ()))); + } + hash_map->table->RemoveAll (); +} + +template +static +inline +bool +_rt_coreclr_hash_map_lookup ( + CONST_HASH_MAP_TYPE *hash_map, + CONST_KEY_TYPE key, + VALUE_TYPE *value) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (HASH_MAP_TYPE::table_type_t::s_NoThrow); + EP_ASSERT (hash_map != NULL && hash_map->table != NULL); + + const typename HASH_MAP_TYPE::table_type_t::element_t *ret = hash_map->table->LookupPtr ((KEY_TYPE)key); + if (ret == NULL) + return false; + *value = ret->Value (); + return true; +} + +template +static +inline +uint32_t +_rt_coreclr_hash_map_count (CONST_HASH_MAP_TYPE *hash_map) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (HASH_MAP_TYPE::table_type_t::s_NoThrow); + EP_ASSERT (hash_map != NULL && hash_map->table != NULL); + + return hash_map->table->GetCount (); +} + +template +static +inline +bool +_rt_coreclr_hash_map_is_valid (CONST_HASH_MAP_TYPE *hash_map) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (HASH_MAP_TYPE::table_type_t::s_NoThrow); + + return (hash_map != NULL && hash_map->table != NULL); +} + +template +static +inline +void +_rt_coreclr_hash_map_remove ( + HASH_MAP_TYPE *hash_map, + CONST_KEY_TYPE key) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (HASH_MAP_TYPE::table_type_t::s_NoThrow); + EP_ASSERT (hash_map != NULL && hash_map->table != NULL); + + const typename HASH_MAP_TYPE::table_type_t::element_t *ret = NULL; + if (hash_map->callbacks.value_free_func) + ret = hash_map->table->LookupPtr ((KEY_TYPE)key); + hash_map->table->Remove ((KEY_TYPE)key); + if (ret) + hash_map->callbacks.value_free_func (reinterpret_cast(static_cast(ret->Value ()))); +} + +template +static +inline +ITERATOR_TYPE +_rt_coreclr_hash_map_iterator_begin (CONST_HASH_MAP_TYPE *hash_map) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (HASH_MAP_TYPE::table_type_t::s_NoThrow); + EP_ASSERT (hash_map != NULL && hash_map->table != NULL); + + return hash_map->table->Begin (); +} + +template +static +inline +bool +_rt_coreclr_hash_map_iterator_end ( + CONST_HASH_MAP_TYPE *hash_map, + CONST_ITERATOR_TYPE *iterator) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (HASH_MAP_TYPE::table_type_t::s_NoThrow); + EP_ASSERT (hash_map != NULL && hash_map->table != NULL && iterator != NULL); + + return (hash_map->table->End () == *iterator); +} + +template +static +inline +void +_rt_coreclr_hash_map_iterator_next (ITERATOR_TYPE *iterator) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (HASH_MAP_TYPE::table_type_t::s_NoThrow); + EP_ASSERT (iterator != NULL); + + (*iterator)++; +} + +template +static +inline +KEY_TYPE +_rt_coreclr_hash_map_iterator_key (CONST_ITERATOR_TYPE *iterator) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (HASH_MAP_TYPE::table_type_t::s_NoThrow); + EP_ASSERT (iterator != NULL); + + return (*iterator)->Key (); +} + +template +static +inline +VALUE_TYPE +_rt_coreclr_hash_map_iterator_value (CONST_ITERATOR_TYPE *iterator) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (HASH_MAP_TYPE::table_type_t::s_NoThrow); + EP_ASSERT (iterator != NULL); + + return (*iterator)->Value (); +} + +#define EP_RT_DEFINE_LIST_PREFIX(prefix_name, list_name, list_type, item_type) \ + static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, list_name, alloc) (list_type *list) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + _rt_coreclr_list_alloc(list); \ + } \ + static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, list_name, free) (list_type *list, void (*callback)(void *)) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + _rt_coreclr_list_free(list, callback); \ + } \ + static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, list_name, clear) (list_type *list, void (*callback)(void *)) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + _rt_coreclr_list_clear(list, callback); \ + } \ + static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, list_name, append) (list_type *list, item_type item) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_list_append(list, item); \ + } \ + static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, list_name, remove) (list_type *list, const item_type item) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + _rt_coreclr_list_remove(list, item); \ + } \ + static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, list_name, find) (const list_type *list, const item_type item_to_find, item_type *found_item) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_list_find(list, item_to_find, found_item); \ + } \ + static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, list_name, is_empty) (const list_type *list) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_list_is_empty(list); \ + } \ + static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, list_name, is_valid) (const list_type *list) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_list_is_valid(list); \ + } + +#undef EP_RT_DEFINE_LIST +#define EP_RT_DEFINE_LIST(list_name, list_type, item_type) \ + EP_RT_DEFINE_LIST_PREFIX(ep, list_name, list_type, item_type) + +#define EP_RT_DEFINE_LIST_ITERATOR_PREFIX(prefix_name, list_name, list_type, iterator_type, item_type) \ + static inline iterator_type EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, list_name, iterator_begin) (const list_type *list) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_list_iterator_begin(list); \ + } \ + static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, list_name, iterator_end) (const list_type *list, const iterator_type *iterator) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_list_iterator_end(list, iterator); \ + } \ + static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, list_name, iterator_next) (iterator_type *iterator) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + _rt_coreclr_list_iterator_next(iterator); \ + } \ + static inline item_type EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, list_name, iterator_value) (const iterator_type *iterator) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_list_iterator_value(iterator); \ + } + +#undef EP_RT_DEFINE_LIST_ITERATOR +#define EP_RT_DEFINE_LIST_ITERATOR(list_name, list_type, iterator_type, item_type) \ + EP_RT_DEFINE_LIST_ITERATOR_PREFIX(ep, list_name, list_type, iterator_type, item_type) + +#define EP_RT_DEFINE_QUEUE_PREFIX(prefix_name, queue_name, queue_type, item_type) \ + static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, queue_name, alloc) (queue_type *queue) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + _rt_coreclr_queue_alloc(queue); \ + } \ + static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, queue_name, free) (queue_type *queue) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + _rt_coreclr_queue_free(queue); \ + } \ + static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, queue_name, pop_head) (queue_type *queue, item_type *item) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_queue_pop_head(queue, item); \ + } \ + static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, queue_name, push_head) (queue_type *queue, item_type item) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_queue_push_head(queue, item); \ + } \ + static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, queue_name, push_tail) (queue_type *queue, item_type item) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_queue_push_tail(queue, item); \ + } \ + static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, queue_name, is_empty) (const queue_type *queue) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_queue_is_empty(queue); \ + } \ + static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, queue_name, is_valid) (const queue_type *queue) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_queue_is_valid(queue); \ + } + +#undef EP_RT_DEFINE_QUEUE +#define EP_RT_DEFINE_QUEUE(queue_name, queue_type, item_type) \ + EP_RT_DEFINE_QUEUE_PREFIX(ep, queue_name, queue_type, item_type) + +#define EP_RT_DEFINE_ARRAY_PREFIX(prefix_name, array_name, array_type, iterator_type, item_type) \ + static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, alloc) (array_type *ep_array) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + _rt_coreclr_array_alloc(ep_array); \ + } \ + static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, alloc_capacity) (array_type *ep_array, size_t capacity) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + _rt_coreclr_array_alloc_capacity(ep_array, capacity); \ + } \ + static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, free) (array_type *ep_array) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + _rt_coreclr_array_free(ep_array); \ + } \ + static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, append) (array_type *ep_array, item_type item) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_array_append (ep_array, item); \ + } \ + static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, clear) (array_type *ep_array) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + _rt_coreclr_array_clear (ep_array); \ + } \ + static inline size_t EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, size) (const array_type *ep_array) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_array_size (ep_array); \ + } \ + static inline item_type * EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, data) (const array_type *ep_array) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_array_data (ep_array); \ + } \ + static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, is_valid) (const array_type *ep_array) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_array_is_valid (ep_array); \ + } + +#define EP_RT_DEFINE_LOCAL_ARRAY_PREFIX(prefix_name, array_name, array_type, iterator_type, item_type) \ + static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, init) (array_type *ep_array) { \ + STATIC_CONTRACT_NOTHROW; \ + } \ + static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, init_capacity) (array_type *ep_array, size_t capacity) { \ + STATIC_CONTRACT_NOTHROW; \ + _rt_coreclr_array_init_capacity(ep_array, capacity); \ + } \ + static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, fini) (array_type *ep_array) { \ + STATIC_CONTRACT_NOTHROW; \ + } + +#undef EP_RT_DEFINE_ARRAY +#define EP_RT_DEFINE_ARRAY(array_name, array_type, iterator_type, item_type) \ + EP_RT_DEFINE_ARRAY_PREFIX(ep, array_name, array_type, iterator_type, item_type) + +#undef EP_RT_DEFINE_LOCAL_ARRAY +#define EP_RT_DEFINE_LOCAL_ARRAY(array_name, array_type, iterator_type, item_type) \ + EP_RT_DEFINE_LOCAL_ARRAY_PREFIX(ep, array_name, array_type, iterator_type, item_type) + +#define EP_RT_DECLARE_LOCAL_ARRAY_VARIABLE(var_name, var_type) \ + var_type::array_type_t _local_ ##var_name; \ + var_type var_name; \ + var_name.array = &_local_ ##var_name + +#define EP_RT_DEFINE_ARRAY_ITERATOR_PREFIX(prefix_name, array_name, array_type, iterator_type, item_type) \ + static inline iterator_type EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, iterator_begin) (const array_type *ep_array) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_array_iterator_begin (ep_array); \ + } \ + static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, iterator_end) (const array_type *ep_array, const iterator_type *iterator) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_array_iterator_end (ep_array, iterator); \ + } \ + static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, iterator_next) (iterator_type *iterator) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + _rt_coreclr_array_iterator_next (iterator); \ + } \ + static inline item_type EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, iterator_value) (const iterator_type *iterator) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_array_iterator_value (iterator); \ + } + +#define EP_RT_DEFINE_ARRAY_REVERSE_ITERATOR_PREFIX(prefix_name, array_name, array_type, iterator_type, item_type) \ + static inline iterator_type EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, reverse_iterator_begin) (const array_type *ep_array) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_array_reverse_iterator_begin (ep_array); \ + } \ + static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, reverse_iterator_end) (const array_type *ep_array, const iterator_type *iterator) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_array_reverse_iterator_end (ep_array, iterator); \ + } \ + static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, reverse_iterator_next) (iterator_type *iterator) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + _rt_coreclr_array_reverse_iterator_next (iterator); \ + } \ + static inline item_type EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, reverse_iterator_value) (const iterator_type *iterator) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_array_reverse_iterator_value (iterator); \ + } + +#undef EP_RT_DEFINE_ARRAY_ITERATOR +#define EP_RT_DEFINE_ARRAY_ITERATOR(array_name, array_type, iterator_type, item_type) \ + EP_RT_DEFINE_ARRAY_ITERATOR_PREFIX(ep, array_name, array_type, iterator_type, item_type) + +#undef EP_RT_DEFINE_ARRAY_REVERSE_ITERATOR +#define EP_RT_DEFINE_ARRAY_REVERSE_ITERATOR(array_name, array_type, iterator_type, item_type) \ + EP_RT_DEFINE_ARRAY_REVERSE_ITERATOR_PREFIX(ep, array_name, array_type, iterator_type, item_type) + +#define EP_RT_DEFINE_HASH_MAP_BASE_PREFIX(prefix_name, hash_map_name, hash_map_type, key_type, value_type) \ + static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, alloc) (hash_map_type *hash_map, uint32_t (*hash_callback)(const void *), bool (*eq_callback)(const void *, const void *), void (*key_free_callback)(void *), void (*value_free_callback)(void *)) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + _rt_coreclr_hash_map_alloc(hash_map, hash_callback, eq_callback, key_free_callback, value_free_callback); \ + } \ + static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, free) (hash_map_type *hash_map) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + _rt_coreclr_hash_map_free(hash_map); \ + } \ + static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, add) (hash_map_type *hash_map, key_type key, value_type value) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_hash_map_add(hash_map, key, value); \ + } \ + static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, remove_all) (hash_map_type *hash_map) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + _rt_coreclr_hash_map_remove_all(hash_map); \ + } \ + static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, lookup) (const hash_map_type *hash_map, const key_type key, value_type *value) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_hash_map_lookup(hash_map, key, value); \ + } \ + static inline uint32_t EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, count) (const hash_map_type *hash_map) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_hash_map_count(hash_map); \ + } \ + static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, is_valid) (const hash_map_type *hash_map) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_hash_map_is_valid(hash_map); \ + } + +#define EP_RT_DEFINE_HASH_MAP_PREFIX(prefix_name, hash_map_name, hash_map_type, key_type, value_type) \ + EP_RT_DEFINE_HASH_MAP_BASE_PREFIX(prefix_name, hash_map_name, hash_map_type, key_type, value_type) \ + static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, add_or_replace) (hash_map_type *hash_map, key_type key, value_type value) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_hash_map_add_or_replace(hash_map, key, value); \ + } \ + +#define EP_RT_DEFINE_HASH_MAP_REMOVE_PREFIX(prefix_name, hash_map_name, hash_map_type, key_type, value_type) \ + EP_RT_DEFINE_HASH_MAP_BASE_PREFIX(prefix_name, hash_map_name, hash_map_type, key_type, value_type) \ + static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, remove) (hash_map_type *hash_map, const key_type key) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + _rt_coreclr_hash_map_remove(hash_map, key); \ + } + +#undef EP_RT_DEFINE_HASH_MAP +#define EP_RT_DEFINE_HASH_MAP(hash_map_name, hash_map_type, key_type, value_type) \ + EP_RT_DEFINE_HASH_MAP_PREFIX(ep, hash_map_name, hash_map_type, key_type, value_type) + +#undef EP_RT_DEFINE_HASH_MAP_REMOVE +#define EP_RT_DEFINE_HASH_MAP_REMOVE(hash_map_name, hash_map_type, key_type, value_type) \ + EP_RT_DEFINE_HASH_MAP_REMOVE_PREFIX(ep, hash_map_name, hash_map_type, key_type, value_type) + +#define EP_RT_DEFINE_HASH_MAP_ITERATOR_PREFIX(prefix_name, hash_map_name, hash_map_type, iterator_type, key_type, value_type) \ + static inline iterator_type EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, iterator_begin) (const hash_map_type *hash_map) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_hash_map_iterator_begin(hash_map); \ + } \ + static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, iterator_end) (const hash_map_type *hash_map, const iterator_type *iterator) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_hash_map_iterator_end(hash_map, iterator); \ + } \ + static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, iterator_next) (iterator_type *iterator) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + _rt_coreclr_hash_map_iterator_next(iterator); \ + } \ + static inline key_type EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, iterator_key) (const iterator_type *iterator) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_hash_map_iterator_key(iterator); \ + } \ + static inline value_type EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, iterator_value) (const iterator_type *iterator) \ + { \ + STATIC_CONTRACT_NOTHROW; \ + return _rt_coreclr_hash_map_iterator_value(iterator); \ + } + +#undef EP_RT_DEFINE_HASH_MAP_ITERATOR +#define EP_RT_DEFINE_HASH_MAP_ITERATOR(hash_map_name, hash_map_type, iterator_type, key_type, value_type) \ + EP_RT_DEFINE_HASH_MAP_ITERATOR_PREFIX(ep, hash_map_name, hash_map_type, iterator_type, key_type, value_type) + +static +inline +ep_rt_lock_handle_t * +ep_rt_coreclr_config_lock_get (void) +{ + STATIC_CONTRACT_NOTHROW; + + extern ep_rt_lock_handle_t _ep_rt_coreclr_config_lock_handle; + return &_ep_rt_coreclr_config_lock_handle; +} + +static +inline +const ep_char8_t * +ep_rt_entrypoint_assembly_name_get_utf8 (void) +{ + STATIC_CONTRACT_NOTHROW; + + AppDomain *app_domain_ref = nullptr; + Assembly *assembly_ref = nullptr; + + app_domain_ref = GetAppDomain (); + if (app_domain_ref != nullptr) + { + assembly_ref = app_domain_ref->GetRootAssembly (); + if (assembly_ref != nullptr) + { + return reinterpret_cast(assembly_ref->GetSimpleName ()); + } + } + + // fallback to the empty string if we can't get assembly info, e.g., if the runtime is + // suspended before an assembly is loaded. + return reinterpret_cast(""); +} + +static +const ep_char8_t * +ep_rt_runtime_version_get_utf8 (void) +{ + STATIC_CONTRACT_NOTHROW; + + return reinterpret_cast(CLR_PRODUCT_VERSION); +} + +/* + * Little-Endian Conversion. + */ + +static +EP_ALWAYS_INLINE +uint16_t +ep_rt_val_uint16_t (uint16_t value) +{ + return value; +} + +static +EP_ALWAYS_INLINE +uint32_t +ep_rt_val_uint32_t (uint32_t value) +{ + return value; +} + +static +EP_ALWAYS_INLINE +uint64_t +ep_rt_val_uint64_t (uint64_t value) +{ + return value; +} + +static +EP_ALWAYS_INLINE +int16_t +ep_rt_val_int16_t (int16_t value) +{ + return value; +} + +static +EP_ALWAYS_INLINE +int32_t +ep_rt_val_int32_t (int32_t value) +{ + return value; +} + +static +EP_ALWAYS_INLINE +int64_t +ep_rt_val_int64_t (int64_t value) +{ + return value; +} + +static +EP_ALWAYS_INLINE +uintptr_t +ep_rt_val_uintptr_t (uintptr_t value) +{ + return value; +} + +/* +* Atomics. +*/ + +static +inline +uint32_t +ep_rt_atomic_inc_uint32_t (volatile uint32_t *value) +{ + STATIC_CONTRACT_NOTHROW; + return static_cast(InterlockedIncrement ((volatile LONG *)(value))); +} + +static +inline +uint32_t +ep_rt_atomic_dec_uint32_t (volatile uint32_t *value) +{ + STATIC_CONTRACT_NOTHROW; + return static_cast(InterlockedDecrement ((volatile LONG *)(value))); +} + +static +inline +int32_t +ep_rt_atomic_inc_int32_t (volatile int32_t *value) +{ + STATIC_CONTRACT_NOTHROW; + return static_cast(InterlockedIncrement ((volatile LONG *)(value))); +} + +static +inline +int32_t +ep_rt_atomic_dec_int32_t (volatile int32_t *value) +{ + STATIC_CONTRACT_NOTHROW; + return static_cast(InterlockedDecrement ((volatile LONG *)(value))); +} + +static +inline +int64_t +ep_rt_atomic_inc_int64_t (volatile int64_t *value) +{ + STATIC_CONTRACT_NOTHROW; + return static_cast(InterlockedIncrement64 ((volatile LONG64 *)(value))); +} + +static +inline +int64_t +ep_rt_atomic_dec_int64_t (volatile int64_t *value) +{ + STATIC_CONTRACT_NOTHROW; + return static_cast(InterlockedDecrement64 ((volatile LONG64 *)(value))); +} + +static +inline +size_t +ep_rt_atomic_compare_exchange_size_t (volatile size_t *target, size_t expected, size_t value) +{ + STATIC_CONTRACT_NOTHROW; + return static_cast(InterlockedCompareExchangeT (target, value, expected)); +} + +static +inline +ep_char8_t * +ep_rt_atomic_compare_exchange_utf8_string (ep_char8_t *volatile *target, ep_char8_t *expected, ep_char8_t *value) +{ + STATIC_CONTRACT_NOTHROW; + return static_cast(InterlockedCompareExchangeT (target, value, expected)); +} + +/* + * EventPipe. + */ + +EP_RT_DEFINE_ARRAY (session_id_array, ep_rt_session_id_array_t, ep_rt_session_id_array_iterator_t, EventPipeSessionID) +EP_RT_DEFINE_ARRAY_ITERATOR (session_id_array, ep_rt_session_id_array_t, ep_rt_session_id_array_iterator_t, EventPipeSessionID) + +EP_RT_DEFINE_ARRAY (execution_checkpoint_array, ep_rt_execution_checkpoint_array_t, ep_rt_execution_checkpoint_array_iterator_t, EventPipeExecutionCheckpoint *) +EP_RT_DEFINE_ARRAY_ITERATOR (execution_checkpoint_array, ep_rt_execution_checkpoint_array_t, ep_rt_execution_checkpoint_array_iterator_t, EventPipeExecutionCheckpoint *) + +static +void +ep_rt_init (void) +{ + STATIC_CONTRACT_NOTHROW; + + extern ep_rt_lock_handle_t _ep_rt_coreclr_config_lock_handle; + extern CrstStatic _ep_rt_coreclr_config_lock; + + _ep_rt_coreclr_config_lock_handle.lock = &_ep_rt_coreclr_config_lock; + _ep_rt_coreclr_config_lock_handle.lock->InitNoThrow (CrstEventPipe, (CrstFlags)(CRST_REENTRANCY | CRST_TAKEN_DURING_SHUTDOWN | CRST_HOST_BREAKABLE)); + + if (CLRConfig::GetConfigValue (CLRConfig::INTERNAL_EventPipeProcNumbers) != 0) { +#ifndef TARGET_UNIX + // setup the windows processor group offset table + uint16_t groups = ::GetActiveProcessorGroupCount (); + extern uint32_t *_ep_rt_coreclr_proc_group_offsets; + _ep_rt_coreclr_proc_group_offsets = new (nothrow) uint32_t [groups]; + if (_ep_rt_coreclr_proc_group_offsets) { + uint32_t procs = 0; + for (uint16_t i = 0; i < procs; ++i) { + _ep_rt_coreclr_proc_group_offsets [i] = procs; + procs += GetActiveProcessorCount (i); + } + } +#endif + } +} + +static +inline +void +ep_rt_init_finish (void) +{ + STATIC_CONTRACT_NOTHROW; +} + +static +inline +void +ep_rt_shutdown (void) +{ + STATIC_CONTRACT_NOTHROW; +} + +static +inline +bool +ep_rt_config_acquire (void) +{ + STATIC_CONTRACT_NOTHROW; + return ep_rt_lock_acquire (ep_rt_coreclr_config_lock_get ()); +} + +static +inline +bool +ep_rt_config_release (void) +{ + STATIC_CONTRACT_NOTHROW; + return ep_rt_lock_release (ep_rt_coreclr_config_lock_get ()); +} + +#ifdef EP_CHECKED_BUILD +static +inline +void +ep_rt_config_requires_lock_held (void) +{ + STATIC_CONTRACT_NOTHROW; + ep_rt_lock_requires_lock_held (ep_rt_coreclr_config_lock_get ()); +} + +static +inline +void +ep_rt_config_requires_lock_not_held (void) +{ + STATIC_CONTRACT_NOTHROW; + ep_rt_lock_requires_lock_not_held (ep_rt_coreclr_config_lock_get ()); +} +#endif + +static +inline +bool +ep_rt_walk_managed_stack_for_thread ( + ep_rt_thread_handle_t thread, + EventPipeStackContents *stack_contents) +{ + STATIC_CONTRACT_NOTHROW; + extern bool ep_rt_coreclr_walk_managed_stack_for_thread (ep_rt_thread_handle_t thread, EventPipeStackContents *stack_contents); + return ep_rt_coreclr_walk_managed_stack_for_thread (thread, stack_contents); +} + +static +inline +bool +ep_rt_method_get_simple_assembly_name ( + ep_rt_method_desc_t *method, + ep_char8_t *name, + size_t name_len) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (method != NULL); + EP_ASSERT (name != NULL); + + const ep_char8_t *assembly_name = method->GetLoaderModule ()->GetAssembly ()->GetSimpleName (); + if (!assembly_name) + return false; + + size_t assembly_name_len = strlen (assembly_name) + 1; + size_t to_copy = assembly_name_len < name_len ? assembly_name_len : name_len; + memcpy (name, assembly_name, to_copy); + name [to_copy - 1] = 0; + + return true; +} + +static +bool +ep_rt_method_get_full_name ( + ep_rt_method_desc_t *method, + ep_char8_t *name, + size_t name_len) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (method != NULL); + EP_ASSERT (name != NULL); + + bool result = true; + EX_TRY + { + SString method_name; + + TypeString::AppendMethodInternal (method_name, method, TypeString::FormatNamespace | TypeString::FormatSignature); + const ep_char8_t *method_name_utf8 = method_name.GetUTF8 (); + if (method_name_utf8) { + size_t method_name_utf8_len = strlen (method_name_utf8) + 1; + size_t to_copy = method_name_utf8_len < name_len ? method_name_utf8_len : name_len; + memcpy (name, method_name_utf8, to_copy); + name [to_copy - 1] = 0; + } else { + result = false; + } + } + EX_CATCH + { + result = false; + } + EX_END_CATCH(SwallowAllExceptions); + + return result; +} + +static +inline +void +ep_rt_provider_config_init (EventPipeProviderConfiguration *provider_config) +{ + STATIC_CONTRACT_NOTHROW; + + if (!ep_rt_utf8_string_compare (ep_config_get_rundown_provider_name_utf8 (), ep_provider_config_get_provider_name (provider_config))) { + MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context.EventPipeProvider.Level = (UCHAR) ep_provider_config_get_logging_level (provider_config); + MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context.EventPipeProvider.EnabledKeywordsBitmask = ep_provider_config_get_keywords (provider_config); + MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context.EventPipeProvider.IsEnabled = true; + } +} + +// This function is auto-generated from /src/scripts/genEventPipe.py +#ifdef TARGET_UNIX +extern "C" void InitProvidersAndEvents (); +#else +extern void InitProvidersAndEvents (); +#endif + +static +void +ep_rt_init_providers_and_events (void) +{ + STATIC_CONTRACT_NOTHROW; + + EX_TRY + { + InitProvidersAndEvents (); + } + EX_CATCH {} + EX_END_CATCH(SwallowAllExceptions); +} + +static +inline +bool +ep_rt_providers_validate_all_disabled (void) +{ + STATIC_CONTRACT_NOTHROW; + + return (!MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context.EventPipeProvider.IsEnabled && + !MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_DOTNET_Context.EventPipeProvider.IsEnabled && + !MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context.EventPipeProvider.IsEnabled); +} + +static +inline +void +ep_rt_prepare_provider_invoke_callback (EventPipeProviderCallbackData *provider_callback_data) +{ + STATIC_CONTRACT_NOTHROW; +} + +static +void +ep_rt_provider_invoke_callback ( + EventPipeCallback callback_func, + const uint8_t *source_id, + unsigned long is_enabled, + uint8_t level, + uint64_t match_any_keywords, + uint64_t match_all_keywords, + EventFilterDescriptor *filter_data, + void *callback_data) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (callback_func != NULL); + + EX_TRY + { + (*callback_func)( + source_id, + is_enabled, + level, + match_any_keywords, + match_all_keywords, + filter_data, + callback_data); + } + EX_CATCH {} + EX_END_CATCH(SwallowAllExceptions); +} + +/* + * EventPipeBuffer. + */ + +EP_RT_DEFINE_ARRAY (buffer_array, ep_rt_buffer_array_t, ep_rt_buffer_array_iterator_t, EventPipeBuffer *) +EP_RT_DEFINE_LOCAL_ARRAY (buffer_array, ep_rt_buffer_array_t, ep_rt_buffer_array_iterator_t, EventPipeBuffer *) +EP_RT_DEFINE_ARRAY_ITERATOR (buffer_array, ep_rt_buffer_array_t, ep_rt_buffer_array_iterator_t, EventPipeBuffer *) + +#undef EP_RT_DECLARE_LOCAL_BUFFER_ARRAY +#define EP_RT_DECLARE_LOCAL_BUFFER_ARRAY(var_name) \ + EP_RT_DECLARE_LOCAL_ARRAY_VARIABLE(var_name, ep_rt_buffer_array_t) + +/* + * EventPipeBufferList. + */ + +EP_RT_DEFINE_ARRAY (buffer_list_array, ep_rt_buffer_list_array_t, ep_rt_buffer_list_array_iterator_t, EventPipeBufferList *) +EP_RT_DEFINE_LOCAL_ARRAY (buffer_list_array, ep_rt_buffer_list_array_t, ep_rt_buffer_list_array_iterator_t, EventPipeBufferList *) +EP_RT_DEFINE_ARRAY_ITERATOR (buffer_list_array, ep_rt_buffer_list_array_t, ep_rt_buffer_list_array_iterator_t, EventPipeBufferList *) + +#undef EP_RT_DECLARE_LOCAL_BUFFER_LIST_ARRAY +#define EP_RT_DECLARE_LOCAL_BUFFER_LIST_ARRAY(var_name) \ + EP_RT_DECLARE_LOCAL_ARRAY_VARIABLE(var_name, ep_rt_buffer_list_array_t) + +/* + * EventPipeEvent. + */ + +EP_RT_DEFINE_LIST (event_list, ep_rt_event_list_t, EventPipeEvent *) +EP_RT_DEFINE_LIST_ITERATOR (event_list, ep_rt_event_list_t, ep_rt_event_list_iterator_t, EventPipeEvent *) + +/* + * EventPipeFile. + */ + +EP_RT_DEFINE_HASH_MAP_REMOVE(metadata_labels_hash, ep_rt_metadata_labels_hash_map_t, EventPipeEvent *, uint32_t) +EP_RT_DEFINE_HASH_MAP(stack_hash, ep_rt_stack_hash_map_t, StackHashKey *, StackHashEntry *) +EP_RT_DEFINE_HASH_MAP_ITERATOR(stack_hash, ep_rt_stack_hash_map_t, ep_rt_stack_hash_map_iterator_t, StackHashKey *, StackHashEntry *) + +/* + * EventPipeProvider. + */ + +EP_RT_DEFINE_LIST (provider_list, ep_rt_provider_list_t, EventPipeProvider *) +EP_RT_DEFINE_LIST_ITERATOR (provider_list, ep_rt_provider_list_t, ep_rt_provider_list_iterator_t, EventPipeProvider *) + +EP_RT_DEFINE_QUEUE (provider_callback_data_queue, ep_rt_provider_callback_data_queue_t, EventPipeProviderCallbackData *) + +static +EventPipeProvider * +ep_rt_provider_list_find_by_name ( + const ep_rt_provider_list_t *list, + const ep_char8_t *name) +{ + STATIC_CONTRACT_NOTHROW; + + // The provider list should be non-NULL, but can be NULL on shutdown. + if (list) { + SList> *provider_list = list->list; + SListElem *element = provider_list->GetHead (); + while (element) { + EventPipeProvider *provider = element->GetValue (); + if (ep_rt_utf8_string_compare (ep_provider_get_provider_name (element->GetValue ()), name) == 0) + return provider; + + element = provider_list->GetNext (element); + } + } + + return NULL; +} + +/* + * EventPipeProviderConfiguration. + */ + +EP_RT_DEFINE_ARRAY (provider_config_array, ep_rt_provider_config_array_t, ep_rt_provider_config_array_iterator_t, EventPipeProviderConfiguration) +EP_RT_DEFINE_ARRAY_ITERATOR (provider_config_array, ep_rt_provider_config_array_t, ep_rt_provider_config_array_iterator_t, EventPipeProviderConfiguration) + +static +inline +bool +ep_rt_config_value_get_enable (void) +{ + STATIC_CONTRACT_NOTHROW; + return CLRConfig::GetConfigValue (CLRConfig::INTERNAL_EnableEventPipe) != 0; +} + +static +inline +ep_char8_t * +ep_rt_config_value_get_config (void) +{ + STATIC_CONTRACT_NOTHROW; + CLRConfigStringHolder value(CLRConfig::GetConfigValue (CLRConfig::INTERNAL_EventPipeConfig)); + return ep_rt_utf16_to_utf8_string (reinterpret_cast(value.GetValue ()), -1); +} + +static +inline +ep_char8_t * +ep_rt_config_value_get_output_path (void) +{ + STATIC_CONTRACT_NOTHROW; + CLRConfigStringHolder value(CLRConfig::GetConfigValue (CLRConfig::INTERNAL_EventPipeOutputPath)); + return ep_rt_utf16_to_utf8_string (reinterpret_cast(value.GetValue ()), -1); +} + +static +inline +uint32_t +ep_rt_config_value_get_circular_mb (void) +{ + STATIC_CONTRACT_NOTHROW; + return CLRConfig::GetConfigValue (CLRConfig::INTERNAL_EventPipeCircularMB); +} + +static +inline +bool +ep_rt_config_value_get_output_streaming (void) +{ + STATIC_CONTRACT_NOTHROW; + return CLRConfig::GetConfigValue (CLRConfig::INTERNAL_EventPipeOutputStreaming) != 0; +} + +/* + * EventPipeSampleProfiler. + */ + +static +inline +void +ep_rt_sample_profiler_write_sampling_event_for_threads ( + ep_rt_thread_handle_t sampling_thread, + EventPipeEvent *sampling_event) +{ + STATIC_CONTRACT_NOTHROW; + + extern void ep_rt_coreclr_sample_profiler_write_sampling_event_for_threads (ep_rt_thread_handle_t sampling_thread, EventPipeEvent *sampling_event); + ep_rt_coreclr_sample_profiler_write_sampling_event_for_threads (sampling_thread, sampling_event); +} + +static +inline +void +ep_rt_notify_profiler_provider_created (EventPipeProvider *provider) +{ + STATIC_CONTRACT_NOTHROW; + +#ifndef DACCESS_COMPILE + // Let the profiler know the provider has been created so it can register if it wants to + BEGIN_PROFILER_CALLBACK (CORProfilerTrackEventPipe ()); + (&g_profControlBlock)->EventPipeProviderCreated (provider); + END_PROFILER_CALLBACK (); +#endif // DACCESS_COMPILE +} + +/* + * EventPipeSessionProvider. + */ + +EP_RT_DEFINE_LIST (session_provider_list, ep_rt_session_provider_list_t, EventPipeSessionProvider *) +EP_RT_DEFINE_LIST_ITERATOR (session_provider_list, ep_rt_session_provider_list_t, ep_rt_session_provider_list_iterator_t, EventPipeSessionProvider *) + +static +EventPipeSessionProvider * +ep_rt_session_provider_list_find_by_name ( + const ep_rt_session_provider_list_t *list, + const ep_char8_t *name) +{ + STATIC_CONTRACT_NOTHROW; + + SList> *provider_list = list->list; + EventPipeSessionProvider *session_provider = NULL; + SListElem *element = provider_list->GetHead (); + while (element) { + EventPipeSessionProvider *candidate = element->GetValue (); + if (ep_rt_utf8_string_compare (ep_session_provider_get_provider_name (candidate), name) == 0) { + session_provider = candidate; + break; + } + element = provider_list->GetNext (element); + } + + return session_provider; +} + +/* + * EventPipeSequencePoint. + */ + +EP_RT_DEFINE_LIST (sequence_point_list, ep_rt_sequence_point_list_t, EventPipeSequencePoint *) +EP_RT_DEFINE_LIST_ITERATOR (sequence_point_list, ep_rt_sequence_point_list_t, ep_rt_sequence_point_list_iterator_t, EventPipeSequencePoint *) + +/* + * EventPipeThread. + */ + +EP_RT_DEFINE_LIST (thread_list, ep_rt_thread_list_t, EventPipeThread *) +EP_RT_DEFINE_LIST_ITERATOR (thread_list, ep_rt_thread_list_t, ep_rt_thread_list_iterator_t, EventPipeThread *) + +EP_RT_DEFINE_ARRAY (thread_array, ep_rt_thread_array_t, ep_rt_thread_array_iterator_t, EventPipeThread *) +EP_RT_DEFINE_LOCAL_ARRAY (thread_array, ep_rt_thread_array_t, ep_rt_thread_array_iterator_t, EventPipeThread *) +EP_RT_DEFINE_ARRAY_ITERATOR (thread_array, ep_rt_thread_array_t, ep_rt_thread_array_iterator_t, EventPipeThread *) + +#undef EP_RT_DECLARE_LOCAL_THREAD_ARRAY +#define EP_RT_DECLARE_LOCAL_THREAD_ARRAY(var_name) \ + EP_RT_DECLARE_LOCAL_ARRAY_VARIABLE(var_name, ep_rt_thread_array_t) + +/* + * EventPipeThreadSessionState. + */ + +EP_RT_DEFINE_LIST (thread_session_state_list, ep_rt_thread_session_state_list_t, EventPipeThreadSessionState *) +EP_RT_DEFINE_LIST_ITERATOR (thread_session_state_list, ep_rt_thread_session_state_list_t, ep_rt_thread_session_state_list_iterator_t, EventPipeThreadSessionState *) + +EP_RT_DEFINE_ARRAY (thread_session_state_array, ep_rt_thread_session_state_array_t, ep_rt_thread_session_state_array_iterator_t, EventPipeThreadSessionState *) +EP_RT_DEFINE_LOCAL_ARRAY (thread_session_state_array, ep_rt_thread_session_state_array_t, ep_rt_thread_session_state_array_iterator_t, EventPipeThreadSessionState *) +EP_RT_DEFINE_ARRAY_ITERATOR (thread_session_state_array, ep_rt_thread_session_state_array_t, ep_rt_thread_session_state_array_iterator_t, EventPipeThreadSessionState *) + +#undef EP_RT_DECLARE_LOCAL_THREAD_SESSION_STATE_ARRAY +#define EP_RT_DECLARE_LOCAL_THREAD_SESSION_STATE_ARRAY(var_name) \ + EP_RT_DECLARE_LOCAL_ARRAY_VARIABLE(var_name, ep_rt_thread_session_state_array_t) + +/* + * Arrays. + */ + +static +inline +uint8_t * +ep_rt_byte_array_alloc (size_t len) +{ + STATIC_CONTRACT_NOTHROW; + return new (nothrow) uint8_t [len]; +} + +static +inline +void +ep_rt_byte_array_free (uint8_t *ptr) +{ + STATIC_CONTRACT_NOTHROW; + + if (ptr) + delete [] ptr; +} + +/* + * Event. + */ + +static +void +ep_rt_wait_event_alloc ( + ep_rt_wait_event_handle_t *wait_event, + bool manual, + bool initial) +{ + STATIC_CONTRACT_NOTHROW; + + EP_ASSERT (wait_event != NULL); + EP_ASSERT (wait_event->event == NULL); + + wait_event->event = new (nothrow) CLREventStatic (); + if (wait_event->event) { + EX_TRY + { + if (manual) + wait_event->event->CreateManualEvent (initial); + else + wait_event->event->CreateAutoEvent (initial); + } + EX_CATCH {} + EX_END_CATCH(SwallowAllExceptions); + } +} + +static +inline +void +ep_rt_wait_event_free (ep_rt_wait_event_handle_t *wait_event) +{ + STATIC_CONTRACT_NOTHROW; + + if (wait_event != NULL && wait_event->event != NULL) { + wait_event->event->CloseEvent (); + delete wait_event->event; + wait_event->event = NULL; + } +} + +static +inline +bool +ep_rt_wait_event_set (ep_rt_wait_event_handle_t *wait_event) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (wait_event != NULL && wait_event->event != NULL); + + return wait_event->event->Set (); +} + +static +int32_t +ep_rt_wait_event_wait ( + ep_rt_wait_event_handle_t *wait_event, + uint32_t timeout, + bool alertable) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (wait_event != NULL && wait_event->event != NULL); + + int32_t result; + EX_TRY + { + result = wait_event->event->Wait (timeout, alertable); + } + EX_CATCH + { + result = -1; + } + EX_END_CATCH(SwallowAllExceptions); + return result; +} + +static +inline +EventPipeWaitHandle +ep_rt_wait_event_get_wait_handle (ep_rt_wait_event_handle_t *wait_event) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (wait_event != NULL && wait_event->event != NULL); + + return reinterpret_cast(wait_event->event->GetHandleUNHOSTED ()); +} + +static +inline +bool +ep_rt_wait_event_is_valid (ep_rt_wait_event_handle_t *wait_event) +{ + STATIC_CONTRACT_NOTHROW; + + if (wait_event == NULL || wait_event->event == NULL) + return false; + + return wait_event->event->IsValid (); +} + +/* + * Misc. + */ + +static +inline +int +ep_rt_get_last_error (void) +{ + STATIC_CONTRACT_NOTHROW; + return ::GetLastError (); +} + +static +inline +bool +ep_rt_process_detach (void) +{ + STATIC_CONTRACT_NOTHROW; + return (bool)g_fProcessDetach; +} + +static +inline +bool +ep_rt_process_shutdown (void) +{ + STATIC_CONTRACT_NOTHROW; + return (bool)g_fEEShutDown; +} + +static +inline +void +ep_rt_create_activity_id ( + uint8_t *activity_id, + uint32_t activity_id_len) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (activity_id != NULL); + EP_ASSERT (activity_id_len == EP_ACTIVITY_ID_SIZE); + + CoCreateGuid (reinterpret_cast(activity_id)); +} + +static +inline +bool +ep_rt_is_running (void) +{ + STATIC_CONTRACT_NOTHROW; + return (bool)g_fEEStarted; +} + +static +inline +void +ep_rt_execute_rundown (ep_rt_execution_checkpoint_array_t *execution_checkpoints) +{ + STATIC_CONTRACT_NOTHROW; + + //TODO: Write execution checkpoint rundown events. + if (CLRConfig::GetConfigValue (CLRConfig::INTERNAL_EventPipeRundown) > 0) { + // Ask the runtime to emit rundown events. + if (g_fEEStarted && !g_fEEShutDown) + ETW::EnumerationLog::EndRundown (); + } +} + +/* + * Objects. + */ + +// STATIC_CONTRACT_NOTHROW +#undef ep_rt_object_alloc +#define ep_rt_object_alloc(obj_type) (new (nothrow) obj_type()) + +// STATIC_CONTRACT_NOTHROW +#undef ep_rt_object_array_alloc +#define ep_rt_object_array_alloc(obj_type,size) (new (nothrow) obj_type [size]()) + +// STATIC_CONTRACT_NOTHROW +#undef ep_rt_object_array_free +#define ep_rt_object_array_free(obj_ptr) do { if (obj_ptr) delete [] obj_ptr; } while(0) + +// STATIC_CONTRACT_NOTHROW +#undef ep_rt_object_free +#define ep_rt_object_free(obj_ptr) do { if (obj_ptr) delete obj_ptr; } while(0) + +/* + * PAL. + */ + +typedef struct _rt_coreclr_thread_params_internal_t { + ep_rt_thread_params_t thread_params; +} rt_coreclr_thread_params_internal_t; + +#undef EP_RT_DEFINE_THREAD_FUNC +#define EP_RT_DEFINE_THREAD_FUNC(name) static ep_rt_thread_start_func_return_t WINAPI name (LPVOID data) + +EP_RT_DEFINE_THREAD_FUNC (ep_rt_thread_coreclr_start_func) +{ + STATIC_CONTRACT_NOTHROW; + + rt_coreclr_thread_params_internal_t *thread_params = reinterpret_cast(data); + DWORD result = thread_params->thread_params.thread_func (thread_params); + if (thread_params->thread_params.thread) + ::DestroyThread (thread_params->thread_params.thread); + delete thread_params; + return result; +} + +static +bool +ep_rt_thread_create ( + void *thread_func, + void *params, + EventPipeThreadType thread_type, + void *id) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (thread_func != NULL); + + bool result = false; + + EX_TRY + { + if (thread_type == EP_THREAD_TYPE_SERVER) + { + DWORD thread_id = 0; + HANDLE server_thread = ::CreateThread (nullptr, 0, reinterpret_cast(thread_func), nullptr, 0, &thread_id); + if (server_thread != NULL) + { + if (id) + { + *reinterpret_cast(id) = thread_id; + } + ::CloseHandle (server_thread); + result = true; + } + } + else if (thread_type == EP_THREAD_TYPE_SESSION || thread_type == EP_THREAD_TYPE_SAMPLING) + { + rt_coreclr_thread_params_internal_t *thread_params = new (nothrow) rt_coreclr_thread_params_internal_t (); + if (thread_params) + { + thread_params->thread_params.thread_type = thread_type; + thread_params->thread_params.thread = SetupUnstartedThread (); + thread_params->thread_params.thread_func = reinterpret_cast(thread_func); + thread_params->thread_params.thread_params = params; + + if (thread_params->thread_params.thread->CreateNewThread (0, ep_rt_thread_coreclr_start_func, thread_params)) + { + if (id) + { + *reinterpret_cast(id) = thread_params->thread_params.thread->GetThreadId (); + } + thread_params->thread_params.thread->SetBackground (TRUE); + thread_params->thread_params.thread->StartThread (); + result = true; + } + else + { + delete thread_params; + } + } + } + } + EX_CATCH + { + result = false; + } + EX_END_CATCH(SwallowAllExceptions); + + return result; +} + +static +inline +void +ep_rt_set_server_name(void) +{ + ::SetThreadName(GetCurrentThread(), W(".NET EventPipe")); +} + +static +inline +void +ep_rt_thread_sleep (uint64_t ns) +{ + STATIC_CONTRACT_NOTHROW; + +#ifdef TARGET_UNIX + PAL_nanosleep (ns); +#else //TARGET_UNIX + const uint32_t NUM_NANOSECONDS_IN_1_MS = 1000000; + ClrSleepEx (static_cast(ns / NUM_NANOSECONDS_IN_1_MS), FALSE); +#endif //TARGET_UNIX +} + +static +inline +uint32_t +ep_rt_current_process_get_id (void) +{ + STATIC_CONTRACT_NOTHROW; + return static_cast(GetCurrentProcessId ()); +} + +static +inline +uint32_t +ep_rt_current_processor_get_number (void) +{ + STATIC_CONTRACT_NOTHROW; + +#ifndef TARGET_UNIX + extern uint32_t *_ep_rt_coreclr_proc_group_offsets; + if (_ep_rt_coreclr_proc_group_offsets) { + PROCESSOR_NUMBER proc; + GetCurrentProcessorNumberEx (&proc); + return _ep_rt_coreclr_proc_group_offsets [proc.Group] + proc.Number; + } +#endif + return 0xFFFFFFFF; +} + +static +inline +uint32_t +ep_rt_processors_get_count (void) +{ + STATIC_CONTRACT_NOTHROW; + + SYSTEM_INFO sys_info = {}; + GetSystemInfo (&sys_info); + return static_cast(sys_info.dwNumberOfProcessors); +} + +static +inline +ep_rt_thread_id_t +ep_rt_current_thread_get_id (void) +{ + STATIC_CONTRACT_NOTHROW; + +#ifdef TARGET_UNIX + return static_cast(::PAL_GetCurrentOSThreadId ()); +#else + return static_cast(::GetCurrentThreadId ()); +#endif +} + +static +inline +int64_t +ep_rt_perf_counter_query (void) +{ + STATIC_CONTRACT_NOTHROW; + + LARGE_INTEGER value; + if (QueryPerformanceCounter (&value)) + return static_cast(value.QuadPart); + else + return 0; +} + +static +inline +int64_t +ep_rt_perf_frequency_query (void) +{ + STATIC_CONTRACT_NOTHROW; + + LARGE_INTEGER value; + if (QueryPerformanceFrequency (&value)) + return static_cast(value.QuadPart); + else + return 0; +} + +static +inline +void +ep_rt_system_time_get (EventPipeSystemTime *system_time) +{ + STATIC_CONTRACT_NOTHROW; + + SYSTEMTIME value; + GetSystemTime (&value); + + EP_ASSERT(system_time != NULL); + ep_system_time_set ( + system_time, + value.wYear, + value.wMonth, + value.wDayOfWeek, + value.wDay, + value.wHour, + value.wMinute, + value.wSecond, + value.wMilliseconds); +} + +static +inline +int64_t +ep_rt_system_timestamp_get (void) +{ + STATIC_CONTRACT_NOTHROW; + + FILETIME value; + GetSystemTimeAsFileTime (&value); + return static_cast(((static_cast(value.dwHighDateTime)) << 32) | static_cast(value.dwLowDateTime)); +} + +static +inline +int32_t +ep_rt_system_get_alloc_granularity (void) +{ + STATIC_CONTRACT_NOTHROW; + return static_cast(g_SystemInfo.dwAllocationGranularity); +} + +static +inline +const ep_char8_t * +ep_rt_os_command_line_get (void) +{ + STATIC_CONTRACT_NOTHROW; + EP_UNREACHABLE ("Can not reach here"); + + return NULL; +} + +static +ep_rt_file_handle_t +ep_rt_file_open_write (const ep_char8_t *path) +{ + STATIC_CONTRACT_NOTHROW; + + ep_char16_t *path_utf16 = ep_rt_utf8_to_utf16le_string (path, -1); + ep_return_null_if_nok (path_utf16 != NULL); + + CFileStream *file_stream = new (nothrow) CFileStream (); + if (file_stream && FAILED (file_stream->OpenForWrite (reinterpret_cast(path_utf16)))) { + delete file_stream; + file_stream = NULL; + } + + ep_rt_utf16_string_free (path_utf16); + return static_cast(file_stream); +} + +static +inline +bool +ep_rt_file_close (ep_rt_file_handle_t file_handle) +{ + STATIC_CONTRACT_NOTHROW; + + // Closed in destructor. + if (file_handle) + delete file_handle; + return true; +} + +static +inline +bool +ep_rt_file_write ( + ep_rt_file_handle_t file_handle, + const uint8_t *buffer, + uint32_t bytes_to_write, + uint32_t *bytes_written) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (buffer != NULL); + + ep_return_false_if_nok (file_handle != NULL); + + ULONG out_count; + HRESULT result = reinterpret_cast(file_handle)->Write (buffer, bytes_to_write, &out_count); + *bytes_written = static_cast(out_count); + return result == S_OK; +} + +static +inline +uint8_t * +ep_rt_valloc0 (size_t buffer_size) +{ + STATIC_CONTRACT_NOTHROW; + return reinterpret_cast(ClrVirtualAlloc (NULL, buffer_size, MEM_COMMIT, PAGE_READWRITE)); +} + +static +inline +void +ep_rt_vfree ( + uint8_t *buffer, + size_t buffer_size) +{ + STATIC_CONTRACT_NOTHROW; + + if (buffer) + ClrVirtualFree (buffer, 0, MEM_RELEASE); +} + +static +inline +uint32_t +ep_rt_temp_path_get ( + ep_char8_t *buffer, + uint32_t buffer_len) +{ + STATIC_CONTRACT_NOTHROW; + EP_UNREACHABLE ("Can not reach here"); + + return 0; +} + +EP_RT_DEFINE_ARRAY (env_array_utf16, ep_rt_env_array_utf16_t, ep_rt_env_array_utf16_iterator_t, ep_char16_t *) +EP_RT_DEFINE_ARRAY_ITERATOR (env_array_utf16, ep_rt_env_array_utf16_t, ep_rt_env_array_utf16_iterator_t, ep_char16_t *) + +static +void +ep_rt_os_environment_get_utf16 (ep_rt_env_array_utf16_t *env_array) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (env_array != NULL); + + LPWSTR envs = GetEnvironmentStringsW (); + if (envs) { + LPWSTR next = envs; + while (*next) { + ep_rt_env_array_utf16_append (env_array, ep_rt_utf16_string_dup (reinterpret_cast(next))); + next += ep_rt_utf16_string_len (reinterpret_cast(next)) + 1; + } + FreeEnvironmentStringsW (envs); + } +} + +/* +* Lock. +*/ + +static +bool +ep_rt_lock_acquire (ep_rt_lock_handle_t *lock) +{ + STATIC_CONTRACT_NOTHROW; + + bool result = true; + EX_TRY + { + if (lock) { + CrstBase::CrstHolderWithState holder (lock->lock); + holder.SuppressRelease (); + } + } + EX_CATCH + { + result = false; + } + EX_END_CATCH(SwallowAllExceptions); + + return result; +} + +static +bool +ep_rt_lock_release (ep_rt_lock_handle_t *lock) +{ + STATIC_CONTRACT_NOTHROW; + + bool result = true; + EX_TRY + { + if (lock) { + CrstBase::UnsafeCrstInverseHolder holder (lock->lock); + holder.SuppressRelease (); + } + } + EX_CATCH + { + result = false; + } + EX_END_CATCH(SwallowAllExceptions); + + return result; +} + +#ifdef EP_CHECKED_BUILD +static +inline +void +ep_rt_lock_requires_lock_held (const ep_rt_lock_handle_t *lock) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (((ep_rt_lock_handle_t *)lock)->lock->OwnedByCurrentThread ()); +} + +static +inline +void +ep_rt_lock_requires_lock_not_held (const ep_rt_lock_handle_t *lock) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (lock->lock == NULL || !((ep_rt_lock_handle_t *)lock)->lock->OwnedByCurrentThread ()); +} +#endif + +/* +* SpinLock. +*/ + +static +void +ep_rt_spin_lock_alloc (ep_rt_spin_lock_handle_t *spin_lock) +{ + STATIC_CONTRACT_NOTHROW; + + EX_TRY + { + spin_lock->lock = new (nothrow) SpinLock (); + spin_lock->lock->Init (LOCK_TYPE_DEFAULT); + } + EX_CATCH {} + EX_END_CATCH(SwallowAllExceptions); +} + +static +inline +void +ep_rt_spin_lock_free (ep_rt_spin_lock_handle_t *spin_lock) +{ + STATIC_CONTRACT_NOTHROW; + + if (spin_lock && spin_lock->lock) { + delete spin_lock->lock; + spin_lock->lock = NULL; + } +} + +static +inline +bool +ep_rt_spin_lock_acquire (ep_rt_spin_lock_handle_t *spin_lock) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (ep_rt_spin_lock_is_valid (spin_lock)); + + SpinLock::AcquireLock (spin_lock->lock); + return true; +} + +static +inline +bool +ep_rt_spin_lock_release (ep_rt_spin_lock_handle_t *spin_lock) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (ep_rt_spin_lock_is_valid (spin_lock)); + + SpinLock::ReleaseLock (spin_lock->lock); + return true; +} + +#ifdef EP_CHECKED_BUILD +static +inline +void +ep_rt_spin_lock_requires_lock_held (const ep_rt_spin_lock_handle_t *spin_lock) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (ep_rt_spin_lock_is_valid (spin_lock)); + EP_ASSERT (spin_lock->lock->OwnedByCurrentThread ()); +} + +static +inline +void +ep_rt_spin_lock_requires_lock_not_held (const ep_rt_spin_lock_handle_t *spin_lock) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (spin_lock->lock == NULL || !spin_lock->lock->OwnedByCurrentThread ()); +} +#endif + +static +inline +bool +ep_rt_spin_lock_is_valid (const ep_rt_spin_lock_handle_t *spin_lock) +{ + STATIC_CONTRACT_NOTHROW; + return (spin_lock != NULL && spin_lock->lock != NULL); +} + +/* + * String. + */ + +static +inline +int +ep_rt_utf8_string_compare ( + const ep_char8_t *str1, + const ep_char8_t *str2) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (str1 != NULL && str2 != NULL); + + return strcmp (reinterpret_cast(str1), reinterpret_cast(str2)); +} + +static +inline +int +ep_rt_utf8_string_compare_ignore_case ( + const ep_char8_t *str1, + const ep_char8_t *str2) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (str1 != NULL && str2 != NULL); + + return _stricmp (reinterpret_cast(str1), reinterpret_cast(str2)); +} + +static +inline +bool +ep_rt_utf8_string_is_null_or_empty (const ep_char8_t *str) +{ + STATIC_CONTRACT_NOTHROW; + + if (str == NULL) + return true; + + while (*str) { + if (!isspace (*str)) + return false; + str++; + } + return true; +} + +static +inline +ep_char8_t * +ep_rt_utf8_string_dup (const ep_char8_t *str) +{ + STATIC_CONTRACT_NOTHROW; + + if (!str) + return NULL; + + return _strdup (str); +} + +static +inline +ep_char8_t * +ep_rt_utf8_string_dup_range (const ep_char8_t *str, const ep_char8_t *strEnd) +{ + ptrdiff_t byte_len = strEnd - str; + ep_char8_t *buffer = reinterpret_cast(malloc(byte_len + 1)); + if (buffer != NULL) + { + memcpy (buffer, str, byte_len); + buffer [byte_len] = '\0'; + } + return buffer; +} + +static +inline +ep_char8_t * +ep_rt_utf8_string_strtok ( + ep_char8_t *str, + const ep_char8_t *delimiter, + ep_char8_t **context) +{ + STATIC_CONTRACT_NOTHROW; + return strtok_s (str, delimiter, context); +} + +// STATIC_CONTRACT_NOTHROW +#undef ep_rt_utf8_string_snprintf +#define ep_rt_utf8_string_snprintf( \ + str, \ + str_len, \ + format, ...) \ +sprintf_s (reinterpret_cast(str), static_cast(str_len), reinterpret_cast(format), __VA_ARGS__) + +static +inline +bool +ep_rt_utf8_string_replace ( + ep_char8_t **str, + const ep_char8_t *strSearch, + const ep_char8_t *strReplacement +) +{ + STATIC_CONTRACT_NOTHROW; + if ((*str) == NULL) + return false; + + ep_char8_t* strFound = strstr(*str, strSearch); + if (strFound != NULL) + { + size_t strSearchLen = strlen(strSearch); + size_t newStrSize = strlen(*str) + strlen(strReplacement) - strSearchLen + 1; + ep_char8_t *newStr = reinterpret_cast(malloc(newStrSize)); + if (newStr == NULL) + { + *str = NULL; + return false; + } + ep_rt_utf8_string_snprintf(newStr, newStrSize, "%.*s%s%s", (int)(strFound - (*str)), *str, strReplacement, strFound + strSearchLen); + ep_rt_utf8_string_free(*str); + *str = newStr; + return true; + } + return false; +} + +static +ep_char16_t * +ep_rt_utf8_to_utf16le_string ( + const ep_char8_t *str, + size_t len) +{ + STATIC_CONTRACT_NOTHROW; + + if (!str) + return NULL; + + COUNT_T len_utf16 = WszMultiByteToWideChar (CP_UTF8, 0, str, static_cast(len), 0, 0); + if (len_utf16 == 0) + return NULL; + + if (static_cast(len) != -1) + len_utf16 += 1; + + ep_char16_t *str_utf16 = reinterpret_cast(malloc (len_utf16 * sizeof (ep_char16_t))); + if (!str_utf16) + return NULL; + + len_utf16 = WszMultiByteToWideChar (CP_UTF8, 0, str, static_cast(len), reinterpret_cast(str_utf16), len_utf16); + if (len_utf16 == 0) { + free (str_utf16); + return NULL; + } + + str_utf16 [len_utf16 - 1] = 0; + return str_utf16; +} + +static +inline +ep_char16_t * +ep_rt_utf16_string_dup (const ep_char16_t *str) +{ + STATIC_CONTRACT_NOTHROW; + + if (!str) + return NULL; + + size_t str_size = (ep_rt_utf16_string_len (str) + 1) * sizeof (ep_char16_t); + ep_char16_t *str_dup = reinterpret_cast(malloc (str_size)); + if (str_dup) + memcpy (str_dup, str, str_size); + return str_dup; +} + +static +inline +void +ep_rt_utf8_string_free (ep_char8_t *str) +{ + STATIC_CONTRACT_NOTHROW; + + if (str) + free (str); +} + +static +inline +size_t +ep_rt_utf16_string_len (const ep_char16_t *str) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (str != NULL); + + return wcslen (reinterpret_cast(str)); +} + +static +ep_char8_t * +ep_rt_utf16_to_utf8_string ( + const ep_char16_t *str, + size_t len) +{ + STATIC_CONTRACT_NOTHROW; + + if (!str) + return NULL; + + COUNT_T size_utf8 = WszWideCharToMultiByte (CP_UTF8, 0, reinterpret_cast(str), static_cast(len), NULL, 0, NULL, NULL); + if (size_utf8 == 0) + return NULL; + + if (static_cast(len) != -1) + size_utf8 += 1; + + ep_char8_t *str_utf8 = reinterpret_cast(malloc (size_utf8)); + if (!str_utf8) + return NULL; + + size_utf8 = WszWideCharToMultiByte (CP_UTF8, 0, reinterpret_cast(str), static_cast(len), reinterpret_cast(str_utf8), size_utf8, NULL, NULL); + if (size_utf8 == 0) { + free (str_utf8); + return NULL; + } + + str_utf8 [size_utf8 - 1] = 0; + return str_utf8; +} + +static +inline +ep_char8_t * +ep_rt_utf16le_to_utf8_string ( + const ep_char16_t *str, + size_t len) +{ + return ep_rt_utf16_to_utf8_string (str, len); +} + +static +inline +void +ep_rt_utf16_string_free (ep_char16_t *str) +{ + STATIC_CONTRACT_NOTHROW; + + if (str) + free (str); +} + +static +inline +const ep_char8_t * +ep_rt_managed_command_line_get (void) +{ + STATIC_CONTRACT_NOTHROW; + EP_UNREACHABLE ("Can not reach here"); + + return NULL; +} + +static +const ep_char8_t * +ep_rt_diagnostics_command_line_get (void) +{ + STATIC_CONTRACT_NOTHROW; + + // In coreclr, this value can change over time, specifically before vs after suspension in diagnostics server. + // The host initializes the runtime in two phases, init and exec assembly. On non-Windows platforms the commandline returned by the runtime + // is different during each phase. We suspend during init where the runtime has populated the commandline with a + // mock value (the full path of the executing assembly) and the actual value isn't populated till the exec assembly phase. + // On Windows this does not apply as the value is retrieved directly from the OS any time it is requested. + // As a result, we cannot actually cache this value. We need to return the _current_ value. + // This function needs to handle freeing the string in order to make it consistent with Mono's version. + // There is a rare chance this may be called on multiple threads, so we attempt to always return the newest value + // and conservatively leak the old value if it changed. This is extremely rare and should only leak 1 string. + extern ep_char8_t *volatile _ep_rt_coreclr_diagnostics_cmd_line; + + ep_char8_t *old_cmd_line = _ep_rt_coreclr_diagnostics_cmd_line; + ep_char8_t *new_cmd_line = ep_rt_utf16_to_utf8_string (reinterpret_cast(GetCommandLineForDiagnostics ()), -1); + if (old_cmd_line && ep_rt_utf8_string_compare (old_cmd_line, new_cmd_line) == 0) { + // same as old, so free the new one + ep_rt_utf8_string_free (new_cmd_line); + } else { + // attempt an update, and give up if you lose the race + if (ep_rt_atomic_compare_exchange_utf8_string (&_ep_rt_coreclr_diagnostics_cmd_line, old_cmd_line, new_cmd_line) != old_cmd_line) { + ep_rt_utf8_string_free (new_cmd_line); + } + // NOTE: If there was a value we purposefully leak it since it may still be in use. + // This leak is *small* (length of the command line) and bounded (should only happen once) + } + + return _ep_rt_coreclr_diagnostics_cmd_line; +} + +/* + * Thread. + */ + +static +inline +EventPipeThreadHolder * +thread_holder_alloc_func (void) +{ + STATIC_CONTRACT_NOTHROW; + EventPipeThreadHolder *instance = ep_thread_holder_alloc (ep_thread_alloc()); + if (instance) + ep_thread_register (ep_thread_holder_get_thread (instance)); + return instance; +} + +static +inline +void +thread_holder_free_func (EventPipeThreadHolder * thread_holder) +{ + STATIC_CONTRACT_NOTHROW; + if (thread_holder) { + ep_thread_unregister (ep_thread_holder_get_thread (thread_holder)); + ep_thread_holder_free (thread_holder); + } +} + +class EventPipeCoreCLRThreadHolderTLS { +public: + EventPipeCoreCLRThreadHolderTLS () + { + STATIC_CONTRACT_NOTHROW; + } + + ~EventPipeCoreCLRThreadHolderTLS () + { + STATIC_CONTRACT_NOTHROW; + + if (m_threadHolder) { + thread_holder_free_func (m_threadHolder); + m_threadHolder = NULL; + } + } + + static inline EventPipeThreadHolder * getThreadHolder () + { + STATIC_CONTRACT_NOTHROW; + return g_threadHolderTLS.m_threadHolder; + } + + static inline EventPipeThreadHolder * createThreadHolder () + { + STATIC_CONTRACT_NOTHROW; + + if (g_threadHolderTLS.m_threadHolder) { + thread_holder_free_func (g_threadHolderTLS.m_threadHolder); + g_threadHolderTLS.m_threadHolder = NULL; + } + g_threadHolderTLS.m_threadHolder = thread_holder_alloc_func (); + return g_threadHolderTLS.m_threadHolder; + } + +private: + EventPipeThreadHolder *m_threadHolder; + static thread_local EventPipeCoreCLRThreadHolderTLS g_threadHolderTLS; +}; + +static +void +ep_rt_thread_setup (void) +{ + STATIC_CONTRACT_NOTHROW; + + Thread* thread_handle = SetupThreadNoThrow (); + EP_ASSERT (thread_handle != NULL); +} + +static +inline +EventPipeThread * +ep_rt_thread_get (void) +{ + STATIC_CONTRACT_NOTHROW; + + EventPipeThreadHolder *thread_holder = EventPipeCoreCLRThreadHolderTLS::getThreadHolder (); + return thread_holder ? ep_thread_holder_get_thread (thread_holder) : NULL; +} + +static +inline +EventPipeThread * +ep_rt_thread_get_or_create (void) +{ + STATIC_CONTRACT_NOTHROW; + + EventPipeThreadHolder *thread_holder = EventPipeCoreCLRThreadHolderTLS::getThreadHolder (); + if (!thread_holder) + thread_holder = EventPipeCoreCLRThreadHolderTLS::createThreadHolder (); + + return ep_thread_holder_get_thread (thread_holder); +} + +static +inline +ep_rt_thread_handle_t +ep_rt_thread_get_handle (void) +{ + STATIC_CONTRACT_NOTHROW; + return GetThreadNULLOk (); +} + +static +inline +ep_rt_thread_id_t +ep_rt_thread_get_id (ep_rt_thread_handle_t thread_handle) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (thread_handle != NULL); + + return ep_rt_uint64_t_to_thread_id_t (thread_handle->GetOSThreadId64 ()); +} + +static +inline +uint64_t +ep_rt_thread_id_t_to_uint64_t (ep_rt_thread_id_t thread_id) +{ + return static_cast(thread_id); +} + +static +inline +ep_rt_thread_id_t +ep_rt_uint64_t_to_thread_id_t (uint64_t thread_id) +{ + return static_cast(thread_id); +} + +static +inline +bool +ep_rt_thread_has_started (ep_rt_thread_handle_t thread_handle) +{ + STATIC_CONTRACT_NOTHROW; + return thread_handle != NULL && thread_handle->HasStarted (); +} + +static +inline +ep_rt_thread_activity_id_handle_t +ep_rt_thread_get_activity_id_handle (void) +{ + STATIC_CONTRACT_NOTHROW; + return GetThread (); +} + +static +inline +const uint8_t * +ep_rt_thread_get_activity_id_cref (ep_rt_thread_activity_id_handle_t activity_id_handle) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (activity_id_handle != NULL); + + return reinterpret_cast(activity_id_handle->GetActivityId ()); +} + +static +inline +void +ep_rt_thread_get_activity_id ( + ep_rt_thread_activity_id_handle_t activity_id_handle, + uint8_t *activity_id, + uint32_t activity_id_len) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (activity_id_handle != NULL); + EP_ASSERT (activity_id != NULL); + EP_ASSERT (activity_id_len == EP_ACTIVITY_ID_SIZE); + + memcpy (activity_id, ep_rt_thread_get_activity_id_cref (activity_id_handle), EP_ACTIVITY_ID_SIZE); +} + +static +inline +void +ep_rt_thread_set_activity_id ( + ep_rt_thread_activity_id_handle_t activity_id_handle, + const uint8_t *activity_id, + uint32_t activity_id_len) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (activity_id_handle != NULL); + EP_ASSERT (activity_id != NULL); + EP_ASSERT (activity_id_len == EP_ACTIVITY_ID_SIZE); + + activity_id_handle->SetActivityId (reinterpret_cast(activity_id)); +} + +#undef EP_YIELD_WHILE +#define EP_YIELD_WHILE(condition) YIELD_WHILE(condition) + +/* + * ThreadSequenceNumberMap. + */ + +EP_RT_DEFINE_HASH_MAP_REMOVE(thread_sequence_number_map, ep_rt_thread_sequence_number_hash_map_t, EventPipeThreadSessionState *, uint32_t) +EP_RT_DEFINE_HASH_MAP_ITERATOR(thread_sequence_number_map, ep_rt_thread_sequence_number_hash_map_t, ep_rt_thread_sequence_number_hash_map_iterator_t, EventPipeThreadSessionState *, uint32_t) + +/* + * Volatile. + */ + +static +inline +uint32_t +ep_rt_volatile_load_uint32_t (const volatile uint32_t *ptr) +{ + STATIC_CONTRACT_NOTHROW; + return VolatileLoad ((const uint32_t *)ptr); +} + +static +inline +uint32_t +ep_rt_volatile_load_uint32_t_without_barrier (const volatile uint32_t *ptr) +{ + STATIC_CONTRACT_NOTHROW; + return VolatileLoadWithoutBarrier ((const uint32_t *)ptr); +} + +static +inline +void +ep_rt_volatile_store_uint32_t ( + volatile uint32_t *ptr, + uint32_t value) +{ + STATIC_CONTRACT_NOTHROW; + VolatileStore ((uint32_t *)ptr, value); +} + +static +inline +void +ep_rt_volatile_store_uint32_t_without_barrier ( + volatile uint32_t *ptr, + uint32_t value) +{ + STATIC_CONTRACT_NOTHROW; + VolatileStoreWithoutBarrier((uint32_t *)ptr, value); +} + +static +inline +uint64_t +ep_rt_volatile_load_uint64_t (const volatile uint64_t *ptr) +{ + STATIC_CONTRACT_NOTHROW; + return VolatileLoad ((const uint64_t *)ptr); +} + +static +inline +uint64_t +ep_rt_volatile_load_uint64_t_without_barrier (const volatile uint64_t *ptr) +{ + STATIC_CONTRACT_NOTHROW; + return VolatileLoadWithoutBarrier ((const uint64_t *)ptr); +} + +static +inline +void +ep_rt_volatile_store_uint64_t ( + volatile uint64_t *ptr, + uint64_t value) +{ + STATIC_CONTRACT_NOTHROW; + VolatileStore ((uint64_t *)ptr, value); +} + +static +inline +void +ep_rt_volatile_store_uint64_t_without_barrier ( + volatile uint64_t *ptr, + uint64_t value) +{ + STATIC_CONTRACT_NOTHROW; + VolatileStoreWithoutBarrier ((uint64_t *)ptr, value); +} + +static +inline +int64_t +ep_rt_volatile_load_int64_t (const volatile int64_t *ptr) +{ + STATIC_CONTRACT_NOTHROW; + return VolatileLoad ((int64_t *)ptr); +} + +static +inline +int64_t +ep_rt_volatile_load_int64_t_without_barrier (const volatile int64_t *ptr) +{ + STATIC_CONTRACT_NOTHROW; + return VolatileLoadWithoutBarrier ((int64_t *)ptr); +} + +static +inline +void +ep_rt_volatile_store_int64_t ( + volatile int64_t *ptr, + int64_t value) +{ + STATIC_CONTRACT_NOTHROW; + VolatileStore ((int64_t *)ptr, value); +} + +static +inline +void +ep_rt_volatile_store_int64_t_without_barrier ( + volatile int64_t *ptr, + int64_t value) +{ + STATIC_CONTRACT_NOTHROW; + VolatileStoreWithoutBarrier ((int64_t *)ptr, value); +} + +static +inline +void * +ep_rt_volatile_load_ptr (volatile void **ptr) +{ + STATIC_CONTRACT_NOTHROW; + return VolatileLoad ((void **)ptr); +} + +static +inline +void * +ep_rt_volatile_load_ptr_without_barrier (volatile void **ptr) +{ + STATIC_CONTRACT_NOTHROW; + return VolatileLoadWithoutBarrier ((void **)ptr); +} + +static +inline +void +ep_rt_volatile_store_ptr ( + volatile void **ptr, + void *value) +{ + STATIC_CONTRACT_NOTHROW; + VolatileStore ((void **)ptr, value); +} + +static +inline +void +ep_rt_volatile_store_ptr_without_barrier ( + volatile void **ptr, + void *value) +{ + STATIC_CONTRACT_NOTHROW; + VolatileStoreWithoutBarrier ((void **)ptr, value); +} + +#endif /* ENABLE_PERFTRACING */ +#endif /* __EVENTPIPE_RT_CORECLR_H__ */ diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-config-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-config-aot.h new file mode 100644 index 0000000000000..30e4ccc7f5437 --- /dev/null +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-config-aot.h @@ -0,0 +1,4 @@ +#ifndef __EVENTPIPE_RT_CONFIG_CORECLR_H__ +#define __EVENTPIPE_RT_CONFIG_CORECLR_H__ + +#endif /* __EVENTPIPE_RT_CONFIG_CORECLR_H__ */ diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h new file mode 100644 index 0000000000000..17cc61bc83280 --- /dev/null +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h @@ -0,0 +1,340 @@ +// Implementation of ep-rt-types.h targeting CoreCLR runtime. +#ifndef __EVENTPIPE_RT_TYPES_CORECLR_H__ +#define __EVENTPIPE_RT_TYPES_CORECLR_H__ + +#include + +#ifdef ENABLE_PERFTRACING +#include "slist.h" + +#ifdef DEBUG +#define EP_CHECKED_BUILD +#endif + +#undef EP_ASSERT +#ifdef EP_CHECKED_BUILD +#define EP_ASSERT(expr) _ASSERTE(expr) +#else +#define EP_ASSERT(expr) +#endif + +#undef EP_UNREACHABLE +#define EP_UNREACHABLE(msg) do { UNREACHABLE_MSG(msg); } while (0) + +#undef EP_LIKELY +#define EP_LIKELY(expr) expr + +#undef EP_UNLIKELY +#define EP_UNLIKELY(expr) expr + +template +struct _rt_coreclr_list_internal_t { + typedef struct SListElem element_type_t; + typedef class SList list_type_t; + list_type_t *list; +}; + +template +struct _rt_coreclr_queue_internal_t { + typedef struct SListElem element_type_t; + typedef class SList queue_type_t; + queue_type_t *queue; +}; + +template +struct _rt_coreclr_array_internal_t { + typedef T element_type_t; + typedef class CQuickArrayList array_type_t; + array_type_t *array; +}; + +template +struct _rt_coreclr_array_iterator_internal_t { + typedef typename _rt_coreclr_array_internal_t::array_type_t array_iterator_type; + array_iterator_type *array; + size_t index; +}; + +typedef struct _rt_coreclr_table_callbacks_t { + void (*key_free_func)(void *); + void (*value_free_func)(void *); +} rt_coreclr_table_callbacks_t; + +template +struct _rt_coreclr_table_default_internal_t { + typedef class SHash > > table_type_t; + rt_coreclr_table_callbacks_t callbacks; + table_type_t *table; +}; + +template +struct _rt_coreclr_table_remove_internal_t { + typedef class SHash< MapSHashTraits > table_type_t; + rt_coreclr_table_callbacks_t callbacks; + table_type_t *table; +}; + +class EventPipeCoreCLRStackHashTraits : public NoRemoveSHashTraits< MapSHashTraits > +{ +public: + typedef typename MapSHashTraits::element_t element_t; + typedef typename MapSHashTraits::count_t count_t; + + typedef StackHashKey * key_t; + + static key_t GetKey (element_t e) + { + extern StackHashKey * ep_stack_hash_entry_get_key (StackHashEntry *); + return ep_stack_hash_entry_get_key (e.Value ()); + } + + static BOOL Equals (key_t k1, key_t k2) + { + extern bool ep_stack_hash_key_equal (const void *, const void *); + return ep_stack_hash_key_equal (k1, k2); + } + + static count_t Hash (key_t k) + { + extern uint32_t ep_stack_hash_key_hash (const void *); + return (count_t)ep_stack_hash_key_hash (k); + } + + static element_t Null () + { + return element_t (NULL, NULL); + } + + static bool IsNull (const element_t &e) + { + return (e.Key () == NULL|| e.Value () == NULL); + } +}; + +template +struct _rt_coreclr_table_custom_internal_t { + typedef class SHash table_type_t; + rt_coreclr_table_callbacks_t callbacks; + table_type_t *table; +}; + +class CLREventStatic; +struct _rt_coreclr_event_internal_t { + CLREventStatic *event; +}; + +class CrstStatic; +struct _rt_coreclr_lock_internal_t { + CrstStatic *lock; +}; + +class SpinLock; +struct _rt_coreclr_spin_lock_internal_t { + SpinLock *lock; +}; + +/* + * EventPipeBuffer. + */ + +#undef ep_rt_buffer_array_t +typedef struct _rt_coreclr_array_internal_t ep_rt_buffer_array_t; + +#undef ep_rt_buffer_array_iterator_t +typedef struct _rt_coreclr_array_iterator_internal_t ep_rt_buffer_array_iterator_t; + +/* + * EventPipeBufferList. + */ + +#undef ep_rt_buffer_list_array_t +typedef struct _rt_coreclr_array_internal_t ep_rt_buffer_list_array_t; + +#undef ep_rt_buffer_list_array_iterator_t +typedef struct _rt_coreclr_array_iterator_internal_t ep_rt_buffer_list_array_iterator_t; + +/* + * EventPipeEvent. + */ + +#undef ep_rt_event_list_t +typedef struct _rt_coreclr_list_internal_t ep_rt_event_list_t; + +#undef ep_rt_event_list_iterator_t +typedef class _rt_coreclr_list_internal_t::list_type_t::Iterator ep_rt_event_list_iterator_t; + +/* + * EventPipeFile. + */ + +#undef ep_rt_metadata_labels_hash_map_t +typedef struct _rt_coreclr_table_remove_internal_t ep_rt_metadata_labels_hash_map_t; + +#undef ep_rt_metadata_labels_hash_map_iterator_t +typedef class _rt_coreclr_table_remove_internal_t::table_type_t::Iterator ep_rt_metadata_labels_hash_map_iterator_t; + +#undef ep_rt_stack_hash_map_t +typedef struct _rt_coreclr_table_custom_internal_t ep_rt_stack_hash_map_t; + +#undef ep_rt_stack_hash_map_iterator_t +typedef class _rt_coreclr_table_custom_internal_t::table_type_t::Iterator ep_rt_stack_hash_map_iterator_t; + +/* + * EventPipeProvider. + */ + +#undef ep_rt_provider_list_t +typedef struct _rt_coreclr_list_internal_t ep_rt_provider_list_t; + +#undef ep_rt_provider_list_iterator_t +typedef class _rt_coreclr_list_internal_t::list_type_t::Iterator ep_rt_provider_list_iterator_t; + +#undef ep_rt_provider_callback_data_queue_t +typedef struct _rt_coreclr_queue_internal_t ep_rt_provider_callback_data_queue_t; + +/* + * EventPipeProviderConfiguration. + */ + +#undef ep_rt_provider_config_array_t +typedef struct _rt_coreclr_array_internal_t ep_rt_provider_config_array_t; + +#undef ep_rt_provider_config_array_iterator_t +typedef struct _rt_coreclr_array_iterator_internal_t ep_rt_provider_config_array_iterator_t; + +/* + * EventPipeSessionProvider. + */ + +#undef ep_rt_session_provider_list_t +typedef struct _rt_coreclr_list_internal_t ep_rt_session_provider_list_t; + +#undef ep_rt_session_provider_list_iterator_t +typedef class _rt_coreclr_list_internal_t::list_type_t::Iterator ep_rt_session_provider_list_iterator_t; + +/* + * EventPipeSequencePoint. + */ + +#undef ep_rt_sequence_point_list_t +typedef struct _rt_coreclr_list_internal_t ep_rt_sequence_point_list_t; + +#undef ep_rt_sequence_point_list_iterator_t +typedef class _rt_coreclr_list_internal_t::list_type_t::Iterator ep_rt_sequence_point_list_iterator_t; + +/* + * EventPipeThread. + */ + +#undef ep_rt_thread_list_t +typedef struct _rt_coreclr_list_internal_t ep_rt_thread_list_t; + +#undef ep_rt_thread_list_iterator_t +typedef class _rt_coreclr_list_internal_t::list_type_t::Iterator ep_rt_thread_list_iterator_t; + +#undef ep_rt_thread_array_t +typedef struct _rt_coreclr_array_internal_t ep_rt_thread_array_t; + +#undef ep_rt_thread_array_iterator_t +typedef struct _rt_coreclr_array_iterator_internal_t ep_rt_thread_array_iterator_t; + +/* + * EventPipeThreadSessionState. + */ + +#undef ep_rt_thread_session_state_list_t +typedef struct _rt_coreclr_list_internal_t ep_rt_thread_session_state_list_t; + +#undef ep_rt_thread_session_state_list_iterator_t +typedef class _rt_coreclr_list_internal_t::list_type_t::Iterator ep_rt_thread_session_state_list_iterator_t; + +#undef ep_rt_thread_session_state_array_t +typedef struct _rt_coreclr_array_internal_t ep_rt_thread_session_state_array_t; + +#undef ep_rt_thread_session_state_array_iterator_t +typedef struct _rt_coreclr_array_iterator_internal_t ep_rt_thread_session_state_array_iterator_t; + +/* + * EventPipe. + */ + +#undef ep_rt_session_id_array_t +typedef struct _rt_coreclr_array_internal_t ep_rt_session_id_array_t; + +#undef ep_rt_session_id_array_iterator_t +typedef struct _rt_coreclr_array_iterator_internal_t ep_rt_session_id_array_iterator_t; + +#undef ep_rt_method_desc_t +typedef class MethodDesc ep_rt_method_desc_t; + +#undef ep_rt_execution_checkpoint_array_t +typedef struct _rt_coreclr_array_internal_t ep_rt_execution_checkpoint_array_t; + +#undef ep_rt_execution_checkpoint_array_iterator_t +typedef struct _rt_coreclr_array_iterator_internal_t ep_rt_execution_checkpoint_array_iterator_t; + +/* + * PAL. + */ + +#undef ep_rt_env_array_utf16_t +typedef struct _rt_coreclr_array_internal_t ep_rt_env_array_utf16_t; + +#undef ep_rt_env_array_utf16_iterator_t +typedef struct _rt_coreclr_array_iterator_internal_t ep_rt_env_array_utf16_iterator_t; + +#undef ep_rt_file_handle_t +typedef class CFileStream * ep_rt_file_handle_t; + +#undef ep_rt_wait_event_handle_t +typedef struct _rt_coreclr_event_internal_t ep_rt_wait_event_handle_t; + +#undef ep_rt_lock_handle_t +typedef struct _rt_coreclr_lock_internal_t ep_rt_lock_handle_t; + +#undef ep_rt_spin_lock_handle_t +typedef _rt_coreclr_spin_lock_internal_t ep_rt_spin_lock_handle_t; + +/* + * Thread. + */ + +#undef ep_rt_thread_handle_t +typedef class Thread * ep_rt_thread_handle_t; + +#undef ep_rt_thread_activity_id_handle_t +typedef class Thread * ep_rt_thread_activity_id_handle_t; + +#undef ep_rt_thread_id_t +#ifndef TARGET_UNIX +typedef DWORD ep_rt_thread_id_t; +#else +typedef size_t ep_rt_thread_id_t; +#endif + +#undef ep_rt_thread_start_func +typedef DWORD (WINAPI *ep_rt_thread_start_func)(LPVOID lpThreadParameter); + +#undef ep_rt_thread_start_func_return_t +typedef DWORD ep_rt_thread_start_func_return_t; + +#undef ep_rt_thread_params_t +typedef struct _rt_coreclr_thread_params_t { + ep_rt_thread_handle_t thread; + EventPipeThreadType thread_type; + ep_rt_thread_start_func thread_func; + void *thread_params; +} ep_rt_thread_params_t; + +/* + * ThreadSequenceNumberMap. + */ + +#undef ep_rt_thread_sequence_number_hash_map_t +typedef struct _rt_coreclr_table_remove_internal_t ep_rt_thread_sequence_number_hash_map_t; + +#undef ep_rt_thread_sequence_number_hash_map_iterator_t +typedef class _rt_coreclr_table_remove_internal_t::table_type_t::Iterator ep_rt_thread_sequence_number_hash_map_iterator_t; + +#endif /* ENABLE_PERFTRACING */ +#endif /* __EVENTPIPE_RT_TYPES_CORECLR_H__ */ From 9cf5f089b3d1bd1f4526950c0f0814d0e41a8040 Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Mon, 9 Jan 2023 07:24:24 -0800 Subject: [PATCH 02/32] change coreclr references to aot --- .../nativeaot/Runtime/eventpipe/ds-rt-aot.h | 11 +- .../Runtime/eventpipe/ds-rt-types-aot.h | 22 +- .../nativeaot/Runtime/eventpipe/ep-rt-aot.cpp | 18 +- .../nativeaot/Runtime/eventpipe/ep-rt-aot.h | 272 +++++++++--------- .../Runtime/eventpipe/ep-rt-config-aot.h | 6 +- .../Runtime/eventpipe/ep-rt-types-aot.h | 120 ++++---- 6 files changed, 224 insertions(+), 225 deletions(-) diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ds-rt-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ds-rt-aot.h index 2742a21684710..87f5c67d39f26 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ds-rt-aot.h +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ds-rt-aot.h @@ -1,12 +1,11 @@ -// Implementation of ds-rt.h targeting Mono runtime. -#ifndef __DIAGNOSTICS_RT_MONO_H__ -#define __DIAGNOSTICS_RT_MONO_H__ +// Implementation of ds-rt.h targeting AOT runtime. +#ifndef __DIAGNOSTICS_RT_AOT_H__ +#define __DIAGNOSTICS_RT_AOT_H__ #include #ifdef ENABLE_PERFTRACING -#include "ep-rt-coreclr.h" -#include +#include "ep-rt-aot.h" #include #include #include @@ -360,4 +359,4 @@ ds_rt_server_log_pause_message (void) } #endif /* ENABLE_PERFTRACING */ -#endif /* __DIAGNOSTICS_RT_MONO_H__ */ +#endif /* __DIAGNOSTICS_RT_AOT_H__ */ diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ds-rt-types-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ds-rt-types-aot.h index 529590fb22cbc..9c01f9f6ff016 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ds-rt-types-aot.h +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ds-rt-types-aot.h @@ -1,40 +1,40 @@ // Implementation of ds-rt-types.h targeting CoreCLR runtime. -#ifndef __DIAGNOSTICS_RT_TYPES_CORECLR_H__ -#define __DIAGNOSTICS_RT_TYPES_CORECLR_H__ +#ifndef __DIAGNOSTICS_RT_TYPES_AOT_H__ +#define __DIAGNOSTICS_RT_TYPES_AOT_H__ #include #ifdef ENABLE_PERFTRACING -#include "ep-rt-types-coreclr.h" +#include "ep-rt-types-aot.h" /* * DiagnosticsIpcPollHandle. */ #undef ds_rt_ipc_poll_handle_array_t -typedef struct _rt_coreclr_array_internal_t ds_rt_ipc_poll_handle_array_t; +typedef struct _rt_aot_array_internal_t ds_rt_ipc_poll_handle_array_t; #undef ds_rt_ipc_poll_handle_array_iterator_t -typedef struct _rt_coreclr_array_iterator_internal_t ds_rt_ipc_poll_handle_array_iterator_t; +typedef struct _rt_aot_array_iterator_internal_t ds_rt_ipc_poll_handle_array_iterator_t; /* * DiagnosticsPort. */ #undef ds_rt_port_array_t -typedef struct _rt_coreclr_array_internal_t ds_rt_port_array_t; +typedef struct _rt_aot_array_internal_t ds_rt_port_array_t; #undef ds_rt_port_array_iterator_t -typedef struct _rt_coreclr_array_iterator_internal_t ds_rt_port_array_iterator_t; +typedef struct _rt_aot_array_iterator_internal_t ds_rt_port_array_iterator_t; #undef ds_rt_port_config_array_t -typedef struct _rt_coreclr_array_internal_t ds_rt_port_config_array_t; +typedef struct _rt_aot_array_internal_t ds_rt_port_config_array_t; #undef ds_rt_port_config_array_iterator_t -typedef struct _rt_coreclr_array_iterator_internal_t ds_rt_port_config_array_iterator_t; +typedef struct _rt_aot_array_iterator_internal_t ds_rt_port_config_array_iterator_t; #undef ds_rt_port_config_array_reverse_iterator_t -typedef struct _rt_coreclr_array_iterator_internal_t ds_rt_port_config_array_reverse_iterator_t; +typedef struct _rt_aot_array_iterator_internal_t ds_rt_port_config_array_reverse_iterator_t; #endif /* ENABLE_PERFTRACING */ -#endif /* __DIAGNOSTICS_RT_TYPES_CORECLR_H__ */ +#endif /* __DIAGNOSTICS_RT_TYPES_AOT_H__ */ diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp index 18aa5126930c7..6dbe40b66fd13 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp @@ -7,15 +7,15 @@ #include #include "threadsuspend.h" -ep_rt_lock_handle_t _ep_rt_coreclr_config_lock_handle; -CrstStatic _ep_rt_coreclr_config_lock; +ep_rt_lock_handle_t _ep_rt_aot_config_lock_handle; +CrstStatic _ep_rt_aot_config_lock; -thread_local EventPipeCoreCLRThreadHolderTLS EventPipeCoreCLRThreadHolderTLS::g_threadHolderTLS; +thread_local EventPipeAotThreadHolderTLS EventPipeAotThreadHolderTLS::g_threadHolderTLS; -ep_char8_t *volatile _ep_rt_coreclr_diagnostics_cmd_line; +ep_char8_t *volatile _ep_rt_aot_diagnostics_cmd_line; #ifndef TARGET_UNIX -uint32_t *_ep_rt_coreclr_proc_group_offsets; +uint32_t *_ep_rt_aot_proc_group_offsets; #endif /* @@ -63,7 +63,7 @@ stack_walk_callback ( } bool -ep_rt_coreclr_walk_managed_stack_for_thread ( +ep_rt_aot_walk_managed_stack_for_thread ( ep_rt_thread_handle_t thread, EventPipeStackContents *stack_contents) { @@ -72,7 +72,7 @@ ep_rt_coreclr_walk_managed_stack_for_thread ( EP_ASSERT (stack_contents != NULL); // Calling into StackWalkFrames in preemptive mode violates the host contract, - // but this contract is not used on CoreCLR. + // but this contract is not used on Aot. CONTRACT_VIOLATION (HostViolation); // Before we call into StackWalkFrames we need to mark GC_ON_TRANSITIONS as FALSE @@ -114,7 +114,7 @@ walk_managed_stack_for_threads ( ep_stack_contents_reset (current_stack_contents); // Walk the stack and write it out as an event. - if (ep_rt_coreclr_walk_managed_stack_for_thread (target_thread, current_stack_contents) && !ep_stack_contents_is_empty (current_stack_contents)) { + if (ep_rt_aot_walk_managed_stack_for_thread (target_thread, current_stack_contents) && !ep_stack_contents_is_empty (current_stack_contents)) { // Set the payload. If the GC mode on suspension > 0, then the thread was in cooperative mode. // Even though there are some cases where this is not managed code, we assume it is managed code here. // If the GC mode on suspension == 0 then the thread was in preemptive mode, which we qualify as external here. @@ -138,7 +138,7 @@ walk_managed_stack_for_threads ( } void -ep_rt_coreclr_sample_profiler_write_sampling_event_for_threads ( +ep_rt_aot_sample_profiler_write_sampling_event_for_threads ( ep_rt_thread_handle_t sampling_thread, EventPipeEvent *sampling_event) { diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h index 482626b51313c..1190d51771d60 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h @@ -1,6 +1,6 @@ // Implementation of ep-rt.h targeting CoreCLR runtime. -#ifndef __EVENTPIPE_RT_CORECLR_H__ -#define __EVENTPIPE_RT_CORECLR_H__ +#ifndef __EVENTPIPE_RT_AOT_H__ +#define __EVENTPIPE_RT_AOT_H__ #include @@ -40,7 +40,7 @@ template static inline void -_rt_coreclr_list_alloc (LIST_TYPE *list) { +_rt_aot_list_alloc (LIST_TYPE *list) { STATIC_CONTRACT_NOTHROW; EP_ASSERT (list != NULL); @@ -51,7 +51,7 @@ template static inline void -_rt_coreclr_list_free ( +_rt_aot_list_free ( LIST_TYPE *list, void (*callback)(void *)) { @@ -74,7 +74,7 @@ template static inline void -_rt_coreclr_list_clear ( +_rt_aot_list_clear ( LIST_TYPE *list, void (*callback)(void *)) { @@ -93,7 +93,7 @@ template static inline bool -_rt_coreclr_list_append ( +_rt_aot_list_append ( LIST_TYPE *list, LIST_ITEM item) { @@ -110,7 +110,7 @@ template static inline bool -_rt_coreclr_list_is_empty (CONST_LIST_TYPE *list) +_rt_aot_list_is_empty (CONST_LIST_TYPE *list) { STATIC_CONTRACT_NOTHROW; EP_ASSERT (list != NULL); @@ -170,7 +170,7 @@ template static inline bool -_rt_coreclr_list_is_valid (CONST_LIST_TYPE *list) +_rt_aot_list_is_valid (CONST_LIST_TYPE *list) { STATIC_CONTRACT_NOTHROW; return (list != NULL && list->list != NULL); @@ -180,7 +180,7 @@ templatelist != NULL); @@ -192,7 +192,7 @@ template static inline void -_rt_coreclr_list_iterator_next (ITERATOR_TYPE *iterator) +_rt_aot_list_iterator_next (ITERATOR_TYPE *iterator) { STATIC_CONTRACT_NOTHROW; EP_ASSERT (iterator != NULL); @@ -218,7 +218,7 @@ template static inline void -_rt_coreclr_queue_alloc (QUEUE_TYPE *queue) +_rt_aot_queue_alloc (QUEUE_TYPE *queue) { STATIC_CONTRACT_NOTHROW; EP_ASSERT (queue != NULL); @@ -242,7 +242,7 @@ template static inline void -_rt_coreclr_queue_free (QUEUE_TYPE *queue) +_rt_aot_queue_free (QUEUE_TYPE *queue) { STATIC_CONTRACT_NOTHROW; EP_ASSERT (queue != NULL); @@ -256,7 +256,7 @@ template static inline bool -_rt_coreclr_queue_pop_head ( +_rt_aot_queue_pop_head ( QUEUE_TYPE *queue, ITEM_TYPE *item) { @@ -279,7 +279,7 @@ template static inline bool -_rt_coreclr_queue_push_head ( +_rt_aot_queue_push_head ( QUEUE_TYPE *queue, ITEM_TYPE item) { @@ -296,7 +296,7 @@ template static inline bool -_rt_coreclr_queue_push_tail ( +_rt_aot_queue_push_tail ( QUEUE_TYPE *queue, ITEM_TYPE item) { @@ -313,7 +313,7 @@ template static inline bool -_rt_coreclr_queue_is_empty (CONST_QUEUE_TYPE *queue) +_rt_aot_queue_is_empty (CONST_QUEUE_TYPE *queue) { STATIC_CONTRACT_NOTHROW; EP_ASSERT (queue != NULL && queue->queue != NULL); @@ -325,7 +325,7 @@ template static inline bool -_rt_coreclr_queue_is_valid (CONST_QUEUE_TYPE *queue) +_rt_aot_queue_is_valid (CONST_QUEUE_TYPE *queue) { STATIC_CONTRACT_NOTHROW; return (queue != NULL && queue->queue != NULL); @@ -335,7 +335,7 @@ template static inline void -_rt_coreclr_array_alloc (ARRAY_TYPE *ep_array) +_rt_aot_array_alloc (ARRAY_TYPE *ep_array) { STATIC_CONTRACT_NOTHROW; EP_ASSERT (ep_array != NULL); @@ -347,7 +347,7 @@ template static inline void -_rt_coreclr_array_alloc_capacity ( +_rt_aot_array_alloc_capacity ( ARRAY_TYPE *ep_array, size_t capacity) { @@ -363,7 +363,7 @@ template static inline void -_rt_coreclr_array_init_capacity ( +_rt_aot_array_init_capacity ( ARRAY_TYPE *ep_array, size_t capacity) { @@ -378,7 +378,7 @@ template static inline void -_rt_coreclr_array_free (ARRAY_TYPE *ep_array) +_rt_aot_array_free (ARRAY_TYPE *ep_array) { STATIC_CONTRACT_NOTHROW; EP_ASSERT (ep_array != NULL); @@ -393,7 +393,7 @@ template static inline bool -_rt_coreclr_array_append ( +_rt_aot_array_append ( ARRAY_TYPE *ep_array, ITEM_TYPE item) { @@ -407,7 +407,7 @@ template static inline void -_rt_coreclr_array_clear (ARRAY_TYPE *ep_array) +_rt_aot_array_clear (ARRAY_TYPE *ep_array) { STATIC_CONTRACT_NOTHROW; EP_ASSERT (ep_array != NULL && ep_array->array != NULL); @@ -421,7 +421,7 @@ template static inline size_t -_rt_coreclr_array_size (CONST_ARRAY_TYPE *ep_array) +_rt_aot_array_size (CONST_ARRAY_TYPE *ep_array) { STATIC_CONTRACT_NOTHROW; EP_ASSERT (ep_array != NULL && ep_array->array != NULL); @@ -433,7 +433,7 @@ templatearray != NULL); @@ -445,7 +445,7 @@ template static inline bool -_rt_coreclr_array_is_valid (CONST_ARRAY_TYPE *ep_array) +_rt_aot_array_is_valid (CONST_ARRAY_TYPE *ep_array) { STATIC_CONTRACT_NOTHROW; return (ep_array->array != NULL); @@ -455,7 +455,7 @@ templatearray != NULL); @@ -470,7 +470,7 @@ template static inline void -_rt_coreclr_array_iterator_next (ITERATOR_TYPE *iterator) +_rt_aot_array_iterator_next (ITERATOR_TYPE *iterator) { STATIC_CONTRACT_NOTHROW; EP_ASSERT (iterator != NULL); @@ -496,7 +496,7 @@ templatearray != NULL); @@ -509,7 +509,7 @@ templatearray != NULL); @@ -524,7 +524,7 @@ template static inline void -_rt_coreclr_array_reverse_iterator_next (ITERATOR_TYPE *iterator) +_rt_aot_array_reverse_iterator_next (ITERATOR_TYPE *iterator) { STATIC_CONTRACT_NOTHROW; EP_ASSERT (iterator != NULL); @@ -550,7 +550,7 @@ templatearray != NULL); @@ -563,7 +563,7 @@ template static inline void -_rt_coreclr_hash_map_alloc ( +_rt_aot_hash_map_alloc ( HASH_MAP_TYPE *hash_map, uint32_t (*hash_callback)(const void *), bool (*eq_callback)(const void *, const void *), @@ -583,7 +583,7 @@ template static inline void -_rt_coreclr_hash_map_free (HASH_MAP_TYPE *hash_map) +_rt_aot_hash_map_free (HASH_MAP_TYPE *hash_map) { STATIC_CONTRACT_NOTHROW; EP_ASSERT (HASH_MAP_TYPE::table_type_t::s_NoThrow); @@ -602,7 +602,7 @@ template static inline bool -_rt_coreclr_hash_map_add ( +_rt_aot_hash_map_add ( HASH_MAP_TYPE *hash_map, KEY_TYPE key, VALUE_TYPE value) @@ -618,7 +618,7 @@ template static inline bool -_rt_coreclr_hash_map_add_or_replace ( +_rt_aot_hash_map_add_or_replace ( HASH_MAP_TYPE *hash_map, KEY_TYPE key, VALUE_TYPE value) @@ -634,7 +634,7 @@ template static inline void -_rt_coreclr_hash_map_remove_all (HASH_MAP_TYPE *hash_map) +_rt_aot_hash_map_remove_all (HASH_MAP_TYPE *hash_map) { STATIC_CONTRACT_NOTHROW; EP_ASSERT (HASH_MAP_TYPE::table_type_t::s_NoThrow); @@ -651,7 +651,7 @@ template static inline void -_rt_coreclr_hash_map_iterator_next (ITERATOR_TYPE *iterator) +_rt_aot_hash_map_iterator_next (ITERATOR_TYPE *iterator) { STATIC_CONTRACT_NOTHROW; EP_ASSERT (HASH_MAP_TYPE::table_type_t::s_NoThrow); @@ -757,7 +757,7 @@ template(list); \ + _rt_aot_list_alloc(list); \ } \ static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, list_name, free) (list_type *list, void (*callback)(void *)) \ { \ STATIC_CONTRACT_NOTHROW; \ - _rt_coreclr_list_free(list, callback); \ + _rt_aot_list_free(list, callback); \ } \ static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, list_name, clear) (list_type *list, void (*callback)(void *)) \ { \ STATIC_CONTRACT_NOTHROW; \ - _rt_coreclr_list_clear(list, callback); \ + _rt_aot_list_clear(list, callback); \ } \ static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, list_name, append) (list_type *list, item_type item) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_list_append(list, item); \ + return _rt_aot_list_append(list, item); \ } \ static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, list_name, remove) (list_type *list, const item_type item) \ { \ STATIC_CONTRACT_NOTHROW; \ - _rt_coreclr_list_remove(list, item); \ + _rt_aot_list_remove(list, item); \ } \ static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, list_name, find) (const list_type *list, const item_type item_to_find, item_type *found_item) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_list_find(list, item_to_find, found_item); \ + return _rt_aot_list_find(list, item_to_find, found_item); \ } \ static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, list_name, is_empty) (const list_type *list) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_list_is_empty(list); \ + return _rt_aot_list_is_empty(list); \ } \ static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, list_name, is_valid) (const list_type *list) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_list_is_valid(list); \ + return _rt_aot_list_is_valid(list); \ } #undef EP_RT_DEFINE_LIST @@ -829,22 +829,22 @@ _rt_coreclr_hash_map_iterator_value (CONST_ITERATOR_TYPE *iterator) static inline iterator_type EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, list_name, iterator_begin) (const list_type *list) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_list_iterator_begin(list); \ + return _rt_aot_list_iterator_begin(list); \ } \ static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, list_name, iterator_end) (const list_type *list, const iterator_type *iterator) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_list_iterator_end(list, iterator); \ + return _rt_aot_list_iterator_end(list, iterator); \ } \ static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, list_name, iterator_next) (iterator_type *iterator) \ { \ STATIC_CONTRACT_NOTHROW; \ - _rt_coreclr_list_iterator_next(iterator); \ + _rt_aot_list_iterator_next(iterator); \ } \ static inline item_type EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, list_name, iterator_value) (const iterator_type *iterator) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_list_iterator_value(iterator); \ + return _rt_aot_list_iterator_value(iterator); \ } #undef EP_RT_DEFINE_LIST_ITERATOR @@ -855,37 +855,37 @@ _rt_coreclr_hash_map_iterator_value (CONST_ITERATOR_TYPE *iterator) static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, queue_name, alloc) (queue_type *queue) \ { \ STATIC_CONTRACT_NOTHROW; \ - _rt_coreclr_queue_alloc(queue); \ + _rt_aot_queue_alloc(queue); \ } \ static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, queue_name, free) (queue_type *queue) \ { \ STATIC_CONTRACT_NOTHROW; \ - _rt_coreclr_queue_free(queue); \ + _rt_aot_queue_free(queue); \ } \ static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, queue_name, pop_head) (queue_type *queue, item_type *item) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_queue_pop_head(queue, item); \ + return _rt_aot_queue_pop_head(queue, item); \ } \ static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, queue_name, push_head) (queue_type *queue, item_type item) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_queue_push_head(queue, item); \ + return _rt_aot_queue_push_head(queue, item); \ } \ static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, queue_name, push_tail) (queue_type *queue, item_type item) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_queue_push_tail(queue, item); \ + return _rt_aot_queue_push_tail(queue, item); \ } \ static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, queue_name, is_empty) (const queue_type *queue) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_queue_is_empty(queue); \ + return _rt_aot_queue_is_empty(queue); \ } \ static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, queue_name, is_valid) (const queue_type *queue) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_queue_is_valid(queue); \ + return _rt_aot_queue_is_valid(queue); \ } #undef EP_RT_DEFINE_QUEUE @@ -896,42 +896,42 @@ _rt_coreclr_hash_map_iterator_value (CONST_ITERATOR_TYPE *iterator) static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, alloc) (array_type *ep_array) \ { \ STATIC_CONTRACT_NOTHROW; \ - _rt_coreclr_array_alloc(ep_array); \ + _rt_aot_array_alloc(ep_array); \ } \ static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, alloc_capacity) (array_type *ep_array, size_t capacity) \ { \ STATIC_CONTRACT_NOTHROW; \ - _rt_coreclr_array_alloc_capacity(ep_array, capacity); \ + _rt_aot_array_alloc_capacity(ep_array, capacity); \ } \ static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, free) (array_type *ep_array) \ { \ STATIC_CONTRACT_NOTHROW; \ - _rt_coreclr_array_free(ep_array); \ + _rt_aot_array_free(ep_array); \ } \ static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, append) (array_type *ep_array, item_type item) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_array_append (ep_array, item); \ + return _rt_aot_array_append (ep_array, item); \ } \ static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, clear) (array_type *ep_array) \ { \ STATIC_CONTRACT_NOTHROW; \ - _rt_coreclr_array_clear (ep_array); \ + _rt_aot_array_clear (ep_array); \ } \ static inline size_t EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, size) (const array_type *ep_array) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_array_size (ep_array); \ + return _rt_aot_array_size (ep_array); \ } \ static inline item_type * EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, data) (const array_type *ep_array) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_array_data (ep_array); \ + return _rt_aot_array_data (ep_array); \ } \ static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, is_valid) (const array_type *ep_array) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_array_is_valid (ep_array); \ + return _rt_aot_array_is_valid (ep_array); \ } #define EP_RT_DEFINE_LOCAL_ARRAY_PREFIX(prefix_name, array_name, array_type, iterator_type, item_type) \ @@ -940,7 +940,7 @@ _rt_coreclr_hash_map_iterator_value (CONST_ITERATOR_TYPE *iterator) } \ static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, init_capacity) (array_type *ep_array, size_t capacity) { \ STATIC_CONTRACT_NOTHROW; \ - _rt_coreclr_array_init_capacity(ep_array, capacity); \ + _rt_aot_array_init_capacity(ep_array, capacity); \ } \ static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, fini) (array_type *ep_array) { \ STATIC_CONTRACT_NOTHROW; \ @@ -963,44 +963,44 @@ _rt_coreclr_hash_map_iterator_value (CONST_ITERATOR_TYPE *iterator) static inline iterator_type EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, iterator_begin) (const array_type *ep_array) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_array_iterator_begin (ep_array); \ + return _rt_aot_array_iterator_begin (ep_array); \ } \ static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, iterator_end) (const array_type *ep_array, const iterator_type *iterator) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_array_iterator_end (ep_array, iterator); \ + return _rt_aot_array_iterator_end (ep_array, iterator); \ } \ static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, iterator_next) (iterator_type *iterator) \ { \ STATIC_CONTRACT_NOTHROW; \ - _rt_coreclr_array_iterator_next (iterator); \ + _rt_aot_array_iterator_next (iterator); \ } \ static inline item_type EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, iterator_value) (const iterator_type *iterator) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_array_iterator_value (iterator); \ + return _rt_aot_array_iterator_value (iterator); \ } #define EP_RT_DEFINE_ARRAY_REVERSE_ITERATOR_PREFIX(prefix_name, array_name, array_type, iterator_type, item_type) \ static inline iterator_type EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, reverse_iterator_begin) (const array_type *ep_array) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_array_reverse_iterator_begin (ep_array); \ + return _rt_aot_array_reverse_iterator_begin (ep_array); \ } \ static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, reverse_iterator_end) (const array_type *ep_array, const iterator_type *iterator) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_array_reverse_iterator_end (ep_array, iterator); \ + return _rt_aot_array_reverse_iterator_end (ep_array, iterator); \ } \ static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, reverse_iterator_next) (iterator_type *iterator) \ { \ STATIC_CONTRACT_NOTHROW; \ - _rt_coreclr_array_reverse_iterator_next (iterator); \ + _rt_aot_array_reverse_iterator_next (iterator); \ } \ static inline item_type EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, array_name, reverse_iterator_value) (const iterator_type *iterator) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_array_reverse_iterator_value (iterator); \ + return _rt_aot_array_reverse_iterator_value (iterator); \ } #undef EP_RT_DEFINE_ARRAY_ITERATOR @@ -1015,37 +1015,37 @@ _rt_coreclr_hash_map_iterator_value (CONST_ITERATOR_TYPE *iterator) static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, alloc) (hash_map_type *hash_map, uint32_t (*hash_callback)(const void *), bool (*eq_callback)(const void *, const void *), void (*key_free_callback)(void *), void (*value_free_callback)(void *)) \ { \ STATIC_CONTRACT_NOTHROW; \ - _rt_coreclr_hash_map_alloc(hash_map, hash_callback, eq_callback, key_free_callback, value_free_callback); \ + _rt_aot_hash_map_alloc(hash_map, hash_callback, eq_callback, key_free_callback, value_free_callback); \ } \ static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, free) (hash_map_type *hash_map) \ { \ STATIC_CONTRACT_NOTHROW; \ - _rt_coreclr_hash_map_free(hash_map); \ + _rt_aot_hash_map_free(hash_map); \ } \ static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, add) (hash_map_type *hash_map, key_type key, value_type value) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_hash_map_add(hash_map, key, value); \ + return _rt_aot_hash_map_add(hash_map, key, value); \ } \ static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, remove_all) (hash_map_type *hash_map) \ { \ STATIC_CONTRACT_NOTHROW; \ - _rt_coreclr_hash_map_remove_all(hash_map); \ + _rt_aot_hash_map_remove_all(hash_map); \ } \ static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, lookup) (const hash_map_type *hash_map, const key_type key, value_type *value) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_hash_map_lookup(hash_map, key, value); \ + return _rt_aot_hash_map_lookup(hash_map, key, value); \ } \ static inline uint32_t EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, count) (const hash_map_type *hash_map) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_hash_map_count(hash_map); \ + return _rt_aot_hash_map_count(hash_map); \ } \ static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, is_valid) (const hash_map_type *hash_map) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_hash_map_is_valid(hash_map); \ + return _rt_aot_hash_map_is_valid(hash_map); \ } #define EP_RT_DEFINE_HASH_MAP_PREFIX(prefix_name, hash_map_name, hash_map_type, key_type, value_type) \ @@ -1053,7 +1053,7 @@ _rt_coreclr_hash_map_iterator_value (CONST_ITERATOR_TYPE *iterator) static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, add_or_replace) (hash_map_type *hash_map, key_type key, value_type value) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_hash_map_add_or_replace(hash_map, key, value); \ + return _rt_aot_hash_map_add_or_replace(hash_map, key, value); \ } \ #define EP_RT_DEFINE_HASH_MAP_REMOVE_PREFIX(prefix_name, hash_map_name, hash_map_type, key_type, value_type) \ @@ -1061,7 +1061,7 @@ _rt_coreclr_hash_map_iterator_value (CONST_ITERATOR_TYPE *iterator) static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, remove) (hash_map_type *hash_map, const key_type key) \ { \ STATIC_CONTRACT_NOTHROW; \ - _rt_coreclr_hash_map_remove(hash_map, key); \ + _rt_aot_hash_map_remove(hash_map, key); \ } #undef EP_RT_DEFINE_HASH_MAP @@ -1076,27 +1076,27 @@ _rt_coreclr_hash_map_iterator_value (CONST_ITERATOR_TYPE *iterator) static inline iterator_type EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, iterator_begin) (const hash_map_type *hash_map) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_hash_map_iterator_begin(hash_map); \ + return _rt_aot_hash_map_iterator_begin(hash_map); \ } \ static inline bool EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, iterator_end) (const hash_map_type *hash_map, const iterator_type *iterator) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_hash_map_iterator_end(hash_map, iterator); \ + return _rt_aot_hash_map_iterator_end(hash_map, iterator); \ } \ static inline void EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, iterator_next) (iterator_type *iterator) \ { \ STATIC_CONTRACT_NOTHROW; \ - _rt_coreclr_hash_map_iterator_next(iterator); \ + _rt_aot_hash_map_iterator_next(iterator); \ } \ static inline key_type EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, iterator_key) (const iterator_type *iterator) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_hash_map_iterator_key(iterator); \ + return _rt_aot_hash_map_iterator_key(iterator); \ } \ static inline value_type EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, hash_map_name, iterator_value) (const iterator_type *iterator) \ { \ STATIC_CONTRACT_NOTHROW; \ - return _rt_coreclr_hash_map_iterator_value(iterator); \ + return _rt_aot_hash_map_iterator_value(iterator); \ } #undef EP_RT_DEFINE_HASH_MAP_ITERATOR @@ -1106,12 +1106,12 @@ _rt_coreclr_hash_map_iterator_value (CONST_ITERATOR_TYPE *iterator) static inline ep_rt_lock_handle_t * -ep_rt_coreclr_config_lock_get (void) +ep_rt_aot_config_lock_get (void) { STATIC_CONTRACT_NOTHROW; - extern ep_rt_lock_handle_t _ep_rt_coreclr_config_lock_handle; - return &_ep_rt_coreclr_config_lock_handle; + extern ep_rt_lock_handle_t _ep_rt_aot_config_lock_handle; + return &_ep_rt_aot_config_lock_handle; } static @@ -1300,22 +1300,22 @@ ep_rt_init (void) { STATIC_CONTRACT_NOTHROW; - extern ep_rt_lock_handle_t _ep_rt_coreclr_config_lock_handle; - extern CrstStatic _ep_rt_coreclr_config_lock; + extern ep_rt_lock_handle_t _ep_rt_aot_config_lock_handle; + extern CrstStatic _ep_rt_aot_config_lock; - _ep_rt_coreclr_config_lock_handle.lock = &_ep_rt_coreclr_config_lock; - _ep_rt_coreclr_config_lock_handle.lock->InitNoThrow (CrstEventPipe, (CrstFlags)(CRST_REENTRANCY | CRST_TAKEN_DURING_SHUTDOWN | CRST_HOST_BREAKABLE)); + _ep_rt_aot_config_lock_handle.lock = &_ep_rt_aot_config_lock; + _ep_rt_aot_config_lock_handle.lock->InitNoThrow (CrstEventPipe, (CrstFlags)(CRST_REENTRANCY | CRST_TAKEN_DURING_SHUTDOWN | CRST_HOST_BREAKABLE)); if (CLRConfig::GetConfigValue (CLRConfig::INTERNAL_EventPipeProcNumbers) != 0) { #ifndef TARGET_UNIX // setup the windows processor group offset table uint16_t groups = ::GetActiveProcessorGroupCount (); - extern uint32_t *_ep_rt_coreclr_proc_group_offsets; - _ep_rt_coreclr_proc_group_offsets = new (nothrow) uint32_t [groups]; - if (_ep_rt_coreclr_proc_group_offsets) { + extern uint32_t *_ep_rt_aot_proc_group_offsets; + _ep_rt_aot_proc_group_offsets = new (nothrow) uint32_t [groups]; + if (_ep_rt_aot_proc_group_offsets) { uint32_t procs = 0; for (uint16_t i = 0; i < procs; ++i) { - _ep_rt_coreclr_proc_group_offsets [i] = procs; + _ep_rt_aot_proc_group_offsets [i] = procs; procs += GetActiveProcessorCount (i); } } @@ -1345,7 +1345,7 @@ bool ep_rt_config_acquire (void) { STATIC_CONTRACT_NOTHROW; - return ep_rt_lock_acquire (ep_rt_coreclr_config_lock_get ()); + return ep_rt_lock_acquire (ep_rt_aot_config_lock_get ()); } static @@ -1354,7 +1354,7 @@ bool ep_rt_config_release (void) { STATIC_CONTRACT_NOTHROW; - return ep_rt_lock_release (ep_rt_coreclr_config_lock_get ()); + return ep_rt_lock_release (ep_rt_aot_config_lock_get ()); } #ifdef EP_CHECKED_BUILD @@ -1364,7 +1364,7 @@ void ep_rt_config_requires_lock_held (void) { STATIC_CONTRACT_NOTHROW; - ep_rt_lock_requires_lock_held (ep_rt_coreclr_config_lock_get ()); + ep_rt_lock_requires_lock_held (ep_rt_aot_config_lock_get ()); } static @@ -1373,7 +1373,7 @@ void ep_rt_config_requires_lock_not_held (void) { STATIC_CONTRACT_NOTHROW; - ep_rt_lock_requires_lock_not_held (ep_rt_coreclr_config_lock_get ()); + ep_rt_lock_requires_lock_not_held (ep_rt_aot_config_lock_get ()); } #endif @@ -1385,8 +1385,8 @@ ep_rt_walk_managed_stack_for_thread ( EventPipeStackContents *stack_contents) { STATIC_CONTRACT_NOTHROW; - extern bool ep_rt_coreclr_walk_managed_stack_for_thread (ep_rt_thread_handle_t thread, EventPipeStackContents *stack_contents); - return ep_rt_coreclr_walk_managed_stack_for_thread (thread, stack_contents); + extern bool ep_rt_aot_walk_managed_stack_for_thread (ep_rt_thread_handle_t thread, EventPipeStackContents *stack_contents); + return ep_rt_aot_walk_managed_stack_for_thread (thread, stack_contents); } static @@ -1673,8 +1673,8 @@ ep_rt_sample_profiler_write_sampling_event_for_threads ( { STATIC_CONTRACT_NOTHROW; - extern void ep_rt_coreclr_sample_profiler_write_sampling_event_for_threads (ep_rt_thread_handle_t sampling_thread, EventPipeEvent *sampling_event); - ep_rt_coreclr_sample_profiler_write_sampling_event_for_threads (sampling_thread, sampling_event); + extern void ep_rt_aot_sample_profiler_write_sampling_event_for_threads (ep_rt_thread_handle_t sampling_thread, EventPipeEvent *sampling_event); + ep_rt_aot_sample_profiler_write_sampling_event_for_threads (sampling_thread, sampling_event); } static @@ -1978,18 +1978,18 @@ ep_rt_execute_rundown (ep_rt_execution_checkpoint_array_t *execution_checkpoints * PAL. */ -typedef struct _rt_coreclr_thread_params_internal_t { +typedef struct _rt_aot_thread_params_internal_t { ep_rt_thread_params_t thread_params; -} rt_coreclr_thread_params_internal_t; +} rt_aot_thread_params_internal_t; #undef EP_RT_DEFINE_THREAD_FUNC #define EP_RT_DEFINE_THREAD_FUNC(name) static ep_rt_thread_start_func_return_t WINAPI name (LPVOID data) -EP_RT_DEFINE_THREAD_FUNC (ep_rt_thread_coreclr_start_func) +EP_RT_DEFINE_THREAD_FUNC (ep_rt_thread_aot_start_func) { STATIC_CONTRACT_NOTHROW; - rt_coreclr_thread_params_internal_t *thread_params = reinterpret_cast(data); + rt_aot_thread_params_internal_t *thread_params = reinterpret_cast(data); DWORD result = thread_params->thread_params.thread_func (thread_params); if (thread_params->thread_params.thread) ::DestroyThread (thread_params->thread_params.thread); @@ -2028,7 +2028,7 @@ ep_rt_thread_create ( } else if (thread_type == EP_THREAD_TYPE_SESSION || thread_type == EP_THREAD_TYPE_SAMPLING) { - rt_coreclr_thread_params_internal_t *thread_params = new (nothrow) rt_coreclr_thread_params_internal_t (); + rt_aot_thread_params_internal_t *thread_params = new (nothrow) rt_aot_thread_params_internal_t (); if (thread_params) { thread_params->thread_params.thread_type = thread_type; @@ -2036,7 +2036,7 @@ ep_rt_thread_create ( thread_params->thread_params.thread_func = reinterpret_cast(thread_func); thread_params->thread_params.thread_params = params; - if (thread_params->thread_params.thread->CreateNewThread (0, ep_rt_thread_coreclr_start_func, thread_params)) + if (thread_params->thread_params.thread->CreateNewThread (0, ep_rt_thread_aot_start_func, thread_params)) { if (id) { @@ -2102,11 +2102,11 @@ ep_rt_current_processor_get_number (void) STATIC_CONTRACT_NOTHROW; #ifndef TARGET_UNIX - extern uint32_t *_ep_rt_coreclr_proc_group_offsets; - if (_ep_rt_coreclr_proc_group_offsets) { + extern uint32_t *_ep_rt_aot_proc_group_offsets; + if (_ep_rt_aot_proc_group_offsets) { PROCESSOR_NUMBER proc; GetCurrentProcessorNumberEx (&proc); - return _ep_rt_coreclr_proc_group_offsets [proc.Group] + proc.Number; + return _ep_rt_aot_proc_group_offsets [proc.Group] + proc.Number; } #endif return 0xFFFFFFFF; @@ -2754,7 +2754,7 @@ ep_rt_diagnostics_command_line_get (void) { STATIC_CONTRACT_NOTHROW; - // In coreclr, this value can change over time, specifically before vs after suspension in diagnostics server. + // In aot, this value can change over time, specifically before vs after suspension in diagnostics server. // The host initializes the runtime in two phases, init and exec assembly. On non-Windows platforms the commandline returned by the runtime // is different during each phase. We suspend during init where the runtime has populated the commandline with a // mock value (the full path of the executing assembly) and the actual value isn't populated till the exec assembly phase. @@ -2763,23 +2763,23 @@ ep_rt_diagnostics_command_line_get (void) // This function needs to handle freeing the string in order to make it consistent with Mono's version. // There is a rare chance this may be called on multiple threads, so we attempt to always return the newest value // and conservatively leak the old value if it changed. This is extremely rare and should only leak 1 string. - extern ep_char8_t *volatile _ep_rt_coreclr_diagnostics_cmd_line; + extern ep_char8_t *volatile _ep_rt_aot_diagnostics_cmd_line; - ep_char8_t *old_cmd_line = _ep_rt_coreclr_diagnostics_cmd_line; + ep_char8_t *old_cmd_line = _ep_rt_aot_diagnostics_cmd_line; ep_char8_t *new_cmd_line = ep_rt_utf16_to_utf8_string (reinterpret_cast(GetCommandLineForDiagnostics ()), -1); if (old_cmd_line && ep_rt_utf8_string_compare (old_cmd_line, new_cmd_line) == 0) { // same as old, so free the new one ep_rt_utf8_string_free (new_cmd_line); } else { // attempt an update, and give up if you lose the race - if (ep_rt_atomic_compare_exchange_utf8_string (&_ep_rt_coreclr_diagnostics_cmd_line, old_cmd_line, new_cmd_line) != old_cmd_line) { + if (ep_rt_atomic_compare_exchange_utf8_string (&_ep_rt_aot_diagnostics_cmd_line, old_cmd_line, new_cmd_line) != old_cmd_line) { ep_rt_utf8_string_free (new_cmd_line); } // NOTE: If there was a value we purposefully leak it since it may still be in use. // This leak is *small* (length of the command line) and bounded (should only happen once) } - return _ep_rt_coreclr_diagnostics_cmd_line; + return _ep_rt_aot_diagnostics_cmd_line; } /* @@ -3157,4 +3157,4 @@ ep_rt_volatile_store_ptr_without_barrier ( } #endif /* ENABLE_PERFTRACING */ -#endif /* __EVENTPIPE_RT_CORECLR_H__ */ +#endif /* __EVENTPIPE_RT_AOT_H__ */ diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-config-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-config-aot.h index 30e4ccc7f5437..d42cad689d5e5 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-config-aot.h +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-config-aot.h @@ -1,4 +1,4 @@ -#ifndef __EVENTPIPE_RT_CONFIG_CORECLR_H__ -#define __EVENTPIPE_RT_CONFIG_CORECLR_H__ +#ifndef __EVENTPIPE_RT_CONFIG_AOT_H__ +#define __EVENTPIPE_RT_CONFIG_AOT_H__ -#endif /* __EVENTPIPE_RT_CONFIG_CORECLR_H__ */ +#endif /* __EVENTPIPE_RT_CONFIG_AOT_H__ */ diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h index 17cc61bc83280..4eed50094dc45 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h @@ -1,6 +1,6 @@ -// Implementation of ep-rt-types.h targeting CoreCLR runtime. -#ifndef __EVENTPIPE_RT_TYPES_CORECLR_H__ -#define __EVENTPIPE_RT_TYPES_CORECLR_H__ +// Implementation of ep-rt-types.h targeting aot runtime. +#ifndef __EVENTPIPE_RT_TYPES_AOT_H__ +#define __EVENTPIPE_RT_TYPES_AOT_H__ #include @@ -28,53 +28,53 @@ #define EP_UNLIKELY(expr) expr template -struct _rt_coreclr_list_internal_t { +struct _rt_aot_list_internal_t { typedef struct SListElem element_type_t; typedef class SList list_type_t; list_type_t *list; }; template -struct _rt_coreclr_queue_internal_t { +struct _rt_aot_queue_internal_t { typedef struct SListElem element_type_t; typedef class SList queue_type_t; queue_type_t *queue; }; template -struct _rt_coreclr_array_internal_t { +struct _rt_aot_array_internal_t { typedef T element_type_t; typedef class CQuickArrayList array_type_t; array_type_t *array; }; template -struct _rt_coreclr_array_iterator_internal_t { - typedef typename _rt_coreclr_array_internal_t::array_type_t array_iterator_type; +struct _rt_aot_array_iterator_internal_t { + typedef typename _rt_aot_array_internal_t::array_type_t array_iterator_type; array_iterator_type *array; size_t index; }; -typedef struct _rt_coreclr_table_callbacks_t { +typedef struct _rt_aot_table_callbacks_t { void (*key_free_func)(void *); void (*value_free_func)(void *); -} rt_coreclr_table_callbacks_t; +} rt_aot_table_callbacks_t; template -struct _rt_coreclr_table_default_internal_t { +struct _rt_aot_table_default_internal_t { typedef class SHash > > table_type_t; - rt_coreclr_table_callbacks_t callbacks; + rt_aot_table_callbacks_t callbacks; table_type_t *table; }; template -struct _rt_coreclr_table_remove_internal_t { +struct _rt_aot_table_remove_internal_t { typedef class SHash< MapSHashTraits > table_type_t; - rt_coreclr_table_callbacks_t callbacks; + rt_aot_table_callbacks_t callbacks; table_type_t *table; }; -class EventPipeCoreCLRStackHashTraits : public NoRemoveSHashTraits< MapSHashTraits > +class EventPipeAotStackHashTraits : public NoRemoveSHashTraits< MapSHashTraits > { public: typedef typename MapSHashTraits::element_t element_t; @@ -112,24 +112,24 @@ class EventPipeCoreCLRStackHashTraits : public NoRemoveSHashTraits< MapSHashTrai }; template -struct _rt_coreclr_table_custom_internal_t { +struct _rt_aot_table_custom_internal_t { typedef class SHash table_type_t; - rt_coreclr_table_callbacks_t callbacks; + rt_aot_table_callbacks_t callbacks; table_type_t *table; }; class CLREventStatic; -struct _rt_coreclr_event_internal_t { +struct _rt_aot_event_internal_t { CLREventStatic *event; }; class CrstStatic; -struct _rt_coreclr_lock_internal_t { +struct _rt_aot_lock_internal_t { CrstStatic *lock; }; class SpinLock; -struct _rt_coreclr_spin_lock_internal_t { +struct _rt_aot_spin_lock_internal_t { SpinLock *lock; }; @@ -138,162 +138,162 @@ struct _rt_coreclr_spin_lock_internal_t { */ #undef ep_rt_buffer_array_t -typedef struct _rt_coreclr_array_internal_t ep_rt_buffer_array_t; +typedef struct _rt_aot_array_internal_t ep_rt_buffer_array_t; #undef ep_rt_buffer_array_iterator_t -typedef struct _rt_coreclr_array_iterator_internal_t ep_rt_buffer_array_iterator_t; +typedef struct _rt_aot_array_iterator_internal_t ep_rt_buffer_array_iterator_t; /* * EventPipeBufferList. */ #undef ep_rt_buffer_list_array_t -typedef struct _rt_coreclr_array_internal_t ep_rt_buffer_list_array_t; +typedef struct _rt_aot_array_internal_t ep_rt_buffer_list_array_t; #undef ep_rt_buffer_list_array_iterator_t -typedef struct _rt_coreclr_array_iterator_internal_t ep_rt_buffer_list_array_iterator_t; +typedef struct _rt_aot_array_iterator_internal_t ep_rt_buffer_list_array_iterator_t; /* * EventPipeEvent. */ #undef ep_rt_event_list_t -typedef struct _rt_coreclr_list_internal_t ep_rt_event_list_t; +typedef struct _rt_aot_list_internal_t ep_rt_event_list_t; #undef ep_rt_event_list_iterator_t -typedef class _rt_coreclr_list_internal_t::list_type_t::Iterator ep_rt_event_list_iterator_t; +typedef class _rt_aot_list_internal_t::list_type_t::Iterator ep_rt_event_list_iterator_t; /* * EventPipeFile. */ #undef ep_rt_metadata_labels_hash_map_t -typedef struct _rt_coreclr_table_remove_internal_t ep_rt_metadata_labels_hash_map_t; +typedef struct _rt_aot_table_remove_internal_t ep_rt_metadata_labels_hash_map_t; #undef ep_rt_metadata_labels_hash_map_iterator_t -typedef class _rt_coreclr_table_remove_internal_t::table_type_t::Iterator ep_rt_metadata_labels_hash_map_iterator_t; +typedef class _rt_aot_table_remove_internal_t::table_type_t::Iterator ep_rt_metadata_labels_hash_map_iterator_t; #undef ep_rt_stack_hash_map_t -typedef struct _rt_coreclr_table_custom_internal_t ep_rt_stack_hash_map_t; +typedef struct _rt_aot_table_custom_internal_t ep_rt_stack_hash_map_t; #undef ep_rt_stack_hash_map_iterator_t -typedef class _rt_coreclr_table_custom_internal_t::table_type_t::Iterator ep_rt_stack_hash_map_iterator_t; +typedef class _rt_aot_table_custom_internal_t::table_type_t::Iterator ep_rt_stack_hash_map_iterator_t; /* * EventPipeProvider. */ #undef ep_rt_provider_list_t -typedef struct _rt_coreclr_list_internal_t ep_rt_provider_list_t; +typedef struct _rt_aot_list_internal_t ep_rt_provider_list_t; #undef ep_rt_provider_list_iterator_t -typedef class _rt_coreclr_list_internal_t::list_type_t::Iterator ep_rt_provider_list_iterator_t; +typedef class _rt_aot_list_internal_t::list_type_t::Iterator ep_rt_provider_list_iterator_t; #undef ep_rt_provider_callback_data_queue_t -typedef struct _rt_coreclr_queue_internal_t ep_rt_provider_callback_data_queue_t; +typedef struct _rt_aot_queue_internal_t ep_rt_provider_callback_data_queue_t; /* * EventPipeProviderConfiguration. */ #undef ep_rt_provider_config_array_t -typedef struct _rt_coreclr_array_internal_t ep_rt_provider_config_array_t; +typedef struct _rt_aot_array_internal_t ep_rt_provider_config_array_t; #undef ep_rt_provider_config_array_iterator_t -typedef struct _rt_coreclr_array_iterator_internal_t ep_rt_provider_config_array_iterator_t; +typedef struct _rt_aot_array_iterator_internal_t ep_rt_provider_config_array_iterator_t; /* * EventPipeSessionProvider. */ #undef ep_rt_session_provider_list_t -typedef struct _rt_coreclr_list_internal_t ep_rt_session_provider_list_t; +typedef struct _rt_aot_list_internal_t ep_rt_session_provider_list_t; #undef ep_rt_session_provider_list_iterator_t -typedef class _rt_coreclr_list_internal_t::list_type_t::Iterator ep_rt_session_provider_list_iterator_t; +typedef class _rt_aot_list_internal_t::list_type_t::Iterator ep_rt_session_provider_list_iterator_t; /* * EventPipeSequencePoint. */ #undef ep_rt_sequence_point_list_t -typedef struct _rt_coreclr_list_internal_t ep_rt_sequence_point_list_t; +typedef struct _rt_aot_list_internal_t ep_rt_sequence_point_list_t; #undef ep_rt_sequence_point_list_iterator_t -typedef class _rt_coreclr_list_internal_t::list_type_t::Iterator ep_rt_sequence_point_list_iterator_t; +typedef class _rt_aot_list_internal_t::list_type_t::Iterator ep_rt_sequence_point_list_iterator_t; /* * EventPipeThread. */ #undef ep_rt_thread_list_t -typedef struct _rt_coreclr_list_internal_t ep_rt_thread_list_t; +typedef struct _rt_aot_list_internal_t ep_rt_thread_list_t; #undef ep_rt_thread_list_iterator_t -typedef class _rt_coreclr_list_internal_t::list_type_t::Iterator ep_rt_thread_list_iterator_t; +typedef class _rt_aot_list_internal_t::list_type_t::Iterator ep_rt_thread_list_iterator_t; #undef ep_rt_thread_array_t -typedef struct _rt_coreclr_array_internal_t ep_rt_thread_array_t; +typedef struct _rt_aot_array_internal_t ep_rt_thread_array_t; #undef ep_rt_thread_array_iterator_t -typedef struct _rt_coreclr_array_iterator_internal_t ep_rt_thread_array_iterator_t; +typedef struct _rt_aot_array_iterator_internal_t ep_rt_thread_array_iterator_t; /* * EventPipeThreadSessionState. */ #undef ep_rt_thread_session_state_list_t -typedef struct _rt_coreclr_list_internal_t ep_rt_thread_session_state_list_t; +typedef struct _rt_aot_list_internal_t ep_rt_thread_session_state_list_t; #undef ep_rt_thread_session_state_list_iterator_t -typedef class _rt_coreclr_list_internal_t::list_type_t::Iterator ep_rt_thread_session_state_list_iterator_t; +typedef class _rt_aot_list_internal_t::list_type_t::Iterator ep_rt_thread_session_state_list_iterator_t; #undef ep_rt_thread_session_state_array_t -typedef struct _rt_coreclr_array_internal_t ep_rt_thread_session_state_array_t; +typedef struct _rt_aot_array_internal_t ep_rt_thread_session_state_array_t; #undef ep_rt_thread_session_state_array_iterator_t -typedef struct _rt_coreclr_array_iterator_internal_t ep_rt_thread_session_state_array_iterator_t; +typedef struct _rt_aot_array_iterator_internal_t ep_rt_thread_session_state_array_iterator_t; /* * EventPipe. */ #undef ep_rt_session_id_array_t -typedef struct _rt_coreclr_array_internal_t ep_rt_session_id_array_t; +typedef struct _rt_aot_array_internal_t ep_rt_session_id_array_t; #undef ep_rt_session_id_array_iterator_t -typedef struct _rt_coreclr_array_iterator_internal_t ep_rt_session_id_array_iterator_t; +typedef struct _rt_aot_array_iterator_internal_t ep_rt_session_id_array_iterator_t; #undef ep_rt_method_desc_t typedef class MethodDesc ep_rt_method_desc_t; #undef ep_rt_execution_checkpoint_array_t -typedef struct _rt_coreclr_array_internal_t ep_rt_execution_checkpoint_array_t; +typedef struct _rt_aot_array_internal_t ep_rt_execution_checkpoint_array_t; #undef ep_rt_execution_checkpoint_array_iterator_t -typedef struct _rt_coreclr_array_iterator_internal_t ep_rt_execution_checkpoint_array_iterator_t; +typedef struct _rt_aot_array_iterator_internal_t ep_rt_execution_checkpoint_array_iterator_t; /* * PAL. */ #undef ep_rt_env_array_utf16_t -typedef struct _rt_coreclr_array_internal_t ep_rt_env_array_utf16_t; +typedef struct _rt_aot_array_internal_t ep_rt_env_array_utf16_t; #undef ep_rt_env_array_utf16_iterator_t -typedef struct _rt_coreclr_array_iterator_internal_t ep_rt_env_array_utf16_iterator_t; +typedef struct _rt_aot_array_iterator_internal_t ep_rt_env_array_utf16_iterator_t; #undef ep_rt_file_handle_t typedef class CFileStream * ep_rt_file_handle_t; #undef ep_rt_wait_event_handle_t -typedef struct _rt_coreclr_event_internal_t ep_rt_wait_event_handle_t; +typedef struct _rt_aot_event_internal_t ep_rt_wait_event_handle_t; #undef ep_rt_lock_handle_t -typedef struct _rt_coreclr_lock_internal_t ep_rt_lock_handle_t; +typedef struct _rt_aot_lock_internal_t ep_rt_lock_handle_t; #undef ep_rt_spin_lock_handle_t -typedef _rt_coreclr_spin_lock_internal_t ep_rt_spin_lock_handle_t; +typedef _rt_aot_spin_lock_internal_t ep_rt_spin_lock_handle_t; /* * Thread. @@ -319,7 +319,7 @@ typedef DWORD (WINAPI *ep_rt_thread_start_func)(LPVOID lpThreadParameter); typedef DWORD ep_rt_thread_start_func_return_t; #undef ep_rt_thread_params_t -typedef struct _rt_coreclr_thread_params_t { +typedef struct _rt_aot_thread_params_t { ep_rt_thread_handle_t thread; EventPipeThreadType thread_type; ep_rt_thread_start_func thread_func; @@ -331,10 +331,10 @@ typedef struct _rt_coreclr_thread_params_t { */ #undef ep_rt_thread_sequence_number_hash_map_t -typedef struct _rt_coreclr_table_remove_internal_t ep_rt_thread_sequence_number_hash_map_t; +typedef struct _rt_aot_table_remove_internal_t ep_rt_thread_sequence_number_hash_map_t; #undef ep_rt_thread_sequence_number_hash_map_iterator_t -typedef class _rt_coreclr_table_remove_internal_t::table_type_t::Iterator ep_rt_thread_sequence_number_hash_map_iterator_t; +typedef class _rt_aot_table_remove_internal_t::table_type_t::Iterator ep_rt_thread_sequence_number_hash_map_iterator_t; #endif /* ENABLE_PERFTRACING */ -#endif /* __EVENTPIPE_RT_TYPES_CORECLR_H__ */ +#endif /* __EVENTPIPE_RT_TYPES_AOT_H__ */ From ac16e8e028fd873e2506b55b2189669ee48c25df Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Mon, 9 Jan 2023 08:28:11 -0800 Subject: [PATCH 03/32] Native AOT runtime implementation --- .../eventpipe/NativeaotEventPipeSupport.h | 22 + .../nativeaot/Runtime/eventpipe/ds-rt-aot.h | 116 +-- .../nativeaot/Runtime/eventpipe/ep-rt-aot.cpp | 110 +-- .../nativeaot/Runtime/eventpipe/ep-rt-aot.h | 826 +++++++++--------- .../Runtime/eventpipe/ep-rt-types-aot.h | 42 +- 5 files changed, 503 insertions(+), 613 deletions(-) create mode 100644 src/coreclr/nativeaot/Runtime/eventpipe/NativeaotEventPipeSupport.h diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/NativeaotEventPipeSupport.h b/src/coreclr/nativeaot/Runtime/eventpipe/NativeaotEventPipeSupport.h new file mode 100644 index 0000000000000..253f147e32d99 --- /dev/null +++ b/src/coreclr/nativeaot/Runtime/eventpipe/NativeaotEventPipeSupport.h @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#ifndef __NativeaotEventPipeSupport_h__ +#define __NativeaotEventPipeSupport_h__ + +// This file is included only when compiling shared EventPipe source files and contains any +// definitions which are needed by these source files but are not available in NativeAOT +// runtime source files. + +// As mentioned PalRedhawk*.cpp, in general we don't want to assume that Windows and +// Redhawk global definitions can co-exist, meaning NativeAOT runtime source files +// generally do not have access to windows.h; that said, the HOST_WIN32 parts of the shared +// EventPipe code are designed to rely on windows.h, so windows.h must be included when +// compiling shared EventPipe source files, and a marker is set to indicate that windows.h +// has been added to the compilation in this manner. + +#include + +#define BUILDING_SHARED_NATIVEAOT_EVENTPIPE_CODE + +#endif // __NativeaotEventPipeSupport_h__ diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ds-rt-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ds-rt-aot.h index 87f5c67d39f26..bd75bc650c8d3 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ds-rt-aot.h +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ds-rt-aot.h @@ -92,12 +92,7 @@ ds_rt_auto_trace_init (void) STATIC_CONTRACT_NOTHROW; #ifdef FEATURE_AUTO_TRACE - EX_TRY - { - auto_trace_init (); - } - EX_CATCH {} - EX_END_CATCH(SwallowAllExceptions); + auto_trace_init (); #endif } @@ -108,12 +103,7 @@ ds_rt_auto_trace_launch (void) STATIC_CONTRACT_NOTHROW; #ifdef FEATURE_AUTO_TRACE - EX_TRY - { - auto_trace_launch (); - } - EX_CATCH {} - EX_END_CATCH(SwallowAllExceptions); + auto_trace_launch (); #endif } @@ -124,12 +114,7 @@ ds_rt_auto_trace_signal (void) STATIC_CONTRACT_NOTHROW; #ifdef FEATURE_AUTO_TRACE - EX_TRY - { - auto_trace_signal (); - } - EX_CATCH {} - EX_END_CATCH(SwallowAllExceptions); + auto_trace_signal (); #endif } @@ -140,12 +125,7 @@ ds_rt_auto_trace_wait (void) STATIC_CONTRACT_NOTHROW; #ifdef FEATURE_AUTO_TRACE - EX_TRY - { - auto_trace_wait (); - } - EX_CATCH {} - EX_END_CATCH(SwallowAllExceptions); + auto_trace_wait (); #endif } @@ -159,7 +139,9 @@ bool ds_rt_config_value_get_enable (void) { STATIC_CONTRACT_NOTHROW; - return CLRConfig::GetConfigValue (CLRConfig::EXTERNAL_EnableDiagnostics) != 0; + + // TODO: EventPipe Configuration values - RhConfig? + return true; } static @@ -167,10 +149,8 @@ inline ep_char8_t * ds_rt_config_value_get_ports (void) { - STATIC_CONTRACT_NOTHROW; - - CLRConfigStringHolder value(CLRConfig::GetConfigValue (CLRConfig::EXTERNAL_DOTNET_DiagnosticPorts)); - return ep_rt_utf16_to_utf8_string (reinterpret_cast(value.GetValue ()), -1); + // TODO: EventPipe Configuration values - RhConfig? + return nullptr; } static @@ -179,7 +159,8 @@ uint32_t ds_rt_config_value_get_default_port_suspend (void) { STATIC_CONTRACT_NOTHROW; - return static_cast(CLRConfig::GetConfigValue (CLRConfig::EXTERNAL_DOTNET_DefaultDiagnosticPortSuspend)); + // TODO: EventPipe Configuration values - RhConfig? + return 0; } /* @@ -197,24 +178,11 @@ ds_rt_generate_core_dump ( STATIC_CONTRACT_NOTHROW; ds_ipc_result_t result = DS_IPC_E_FAIL; - EX_TRY - { - uint32_t flags = ds_generate_core_dump_command_payload_get_flags(payload); - if (commandId == DS_DUMP_COMMANDID_GENERATE_CORE_DUMP) - { - // For the old commmand, this payload field is a bool of whether to enable logging - flags = flags != 0 ? GenerateDumpFlagsLoggingEnabled : 0; - } - LPCWSTR dumpName = reinterpret_cast(ds_generate_core_dump_command_payload_get_dump_name (payload)); - int32_t dumpType = static_cast(ds_generate_core_dump_command_payload_get_dump_type (payload)); - if (GenerateDump(dumpName, dumpType, flags, errorMessageBuffer, cbErrorMessageBuffer)) - { - result = DS_IPC_S_OK; - } - } - EX_CATCH {} - EX_END_CATCH(SwallowAllExceptions); - return result; + uint32_t flags = ds_generate_core_dump_command_payload_get_flags(payload); + // TODO: Generate an exception dump + __debugbreak(); + + return 0; } /* @@ -233,10 +201,11 @@ ds_rt_transport_get_default_name ( const ep_char8_t *suffix) { STATIC_CONTRACT_NOTHROW; - -#ifdef TARGET_UNIX - PAL_GetTransportName (name_len, name, prefix, id, group_id, suffix); -#endif + + // TODO: PAL_GetTransportName is defined in coreclr\pal\inc\pal.h +// #ifdef TARGET_UNIX +// PAL_GetTransportName (name_len, name, prefix, id, group_id, suffix); +// #endif return true; } @@ -289,14 +258,11 @@ ds_rt_profiler_attach (DiagnosticsAttachProfilerCommandPayload *payload) ClrFlsSetThreadType (ThreadType_ProfAPI_Attach); HRESULT hr = S_OK; - EX_TRY { - hr = ProfilingAPIUtility::LoadProfilerForAttach (reinterpret_cast(ds_attach_profiler_command_payload_get_profiler_guid_cref (payload)), - reinterpret_cast(ds_attach_profiler_command_payload_get_profiler_path (payload)), - reinterpret_cast(ds_attach_profiler_command_payload_get_client_data (payload)), - static_cast(ds_attach_profiler_command_payload_get_client_data_len (payload)), - static_cast(ds_attach_profiler_command_payload_get_attach_timeout (payload))); - } - EX_CATCH_HRESULT (hr); + hr = ProfilingAPIUtility::LoadProfilerForAttach (reinterpret_cast(ds_attach_profiler_command_payload_get_profiler_guid_cref (payload)), + reinterpret_cast(ds_attach_profiler_command_payload_get_profiler_path (payload)), + reinterpret_cast(ds_attach_profiler_command_payload_get_client_data (payload)), + static_cast(ds_attach_profiler_command_payload_get_client_data_len (payload)), + static_cast(ds_attach_profiler_command_payload_get_attach_timeout (payload))); // Clear the flag so this thread isn't permanently marked as the attach thread. ClrFlsClearThreadType (ThreadType_ProfAPI_Attach); @@ -312,14 +278,11 @@ ds_rt_profiler_startup (DiagnosticsStartupProfilerCommandPayload *payload) STATIC_CONTRACT_NOTHROW; HRESULT hr = S_OK; - EX_TRY { - StoredProfilerNode *profilerData = new StoredProfilerNode(); - profilerData->guid = *(reinterpret_cast(ds_startup_profiler_command_payload_get_profiler_guid_cref (payload))); - profilerData->path.Set(reinterpret_cast(ds_startup_profiler_command_payload_get_profiler_path (payload))); + StoredProfilerNode *profilerData = new StoredProfilerNode(); + profilerData->guid = *(reinterpret_cast(ds_startup_profiler_command_payload_get_profiler_guid_cref (payload))); + profilerData->path.Set(reinterpret_cast(ds_startup_profiler_command_payload_get_profiler_path (payload))); - g_profControlBlock.storedProfilers.InsertHead(profilerData); - } - EX_CATCH_HRESULT (hr); + g_profControlBlock.storedProfilers.InsertHead(profilerData); return hr; } @@ -329,7 +292,9 @@ static uint32_t ds_rt_set_environment_variable (const ep_char16_t *name, const ep_char16_t *value) { - return SetEnvironmentVariableW(reinterpret_cast(name), reinterpret_cast(value)) ? S_OK : HRESULT_FROM_WIN32(GetLastError()); + // return SetEnvironmentVariableW(reinterpret_cast(name), reinterpret_cast(value)) ? S_OK : HRESULT_FROM_WIN32(GetLastError()); + __debugbreak(); + return 0xffff; } /* @@ -343,19 +308,8 @@ ds_rt_server_log_pause_message (void) STATIC_CONTRACT_NOTHROW; const char diagPortsName[] = "DOTNET_DiagnosticPorts"; - CLRConfigNoCache diagPorts = CLRConfigNoCache::Get(diagPortsName); - LPCSTR ports = nullptr; - if (diagPorts.IsSet()) - { - ports = diagPorts.AsString(); - } - - uint32_t port_suspended = ds_rt_config_value_get_default_port_suspend(); - - printf("The runtime has been configured to pause during startup and is awaiting a Diagnostics IPC ResumeStartup command from a Diagnostic Port.\n"); - printf("%s=\"%s\"\n", diagPortsName, ports == nullptr ? "" : ports); - printf("DOTNET_DefaultDiagnosticPortSuspend=%u\n", port_suspended); - fflush(stdout); + // TODO: Cannot find nocache versions of RhConfig + __debugbreak(); } #endif /* ENABLE_PERFTRACING */ diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp index 6dbe40b66fd13..a40deb050314c 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp @@ -5,7 +5,6 @@ #include #include #include -#include "threadsuspend.h" ep_rt_lock_handle_t _ep_rt_aot_config_lock_handle; CrstStatic _ep_rt_aot_config_lock; @@ -22,11 +21,6 @@ uint32_t *_ep_rt_aot_proc_group_offsets; * Forward declares of all static functions. */ -static -StackWalkAction -stack_walk_callback ( - CrawlFrame *frame, - EventPipeStackContents *stack_contents); static void @@ -34,59 +28,14 @@ walk_managed_stack_for_threads ( ep_rt_thread_handle_t sampling_thread, EventPipeEvent *sampling_event); -static -StackWalkAction -stack_walk_callback ( - CrawlFrame *frame, - EventPipeStackContents *stack_contents) -{ - STATIC_CONTRACT_NOTHROW; - EP_ASSERT (frame != NULL); - EP_ASSERT (stack_contents != NULL); - - // Get the IP. - UINT_PTR control_pc = (UINT_PTR)frame->GetRegisterSet ()->ControlPC; - if (control_pc == NULL) { - if (ep_stack_contents_get_length (stack_contents) == 0) { - // This happens for pinvoke stubs on the top of the stack. - return SWA_CONTINUE; - } - } - - EP_ASSERT (control_pc != NULL); - - // Add the IP to the captured stack. - ep_stack_contents_append (stack_contents, control_pc, frame->GetFunction ()); - - // Continue the stack walk. - return SWA_CONTINUE; -} bool ep_rt_aot_walk_managed_stack_for_thread ( ep_rt_thread_handle_t thread, EventPipeStackContents *stack_contents) { - STATIC_CONTRACT_NOTHROW; - EP_ASSERT (thread != NULL); - EP_ASSERT (stack_contents != NULL); - - // Calling into StackWalkFrames in preemptive mode violates the host contract, - // but this contract is not used on Aot. - CONTRACT_VIOLATION (HostViolation); - - // Before we call into StackWalkFrames we need to mark GC_ON_TRANSITIONS as FALSE - // because under GCStress runs (GCStress=0x3), a GC will be triggered for every transition, - // which will cause the GC to try to walk the stack while we are in the middle of walking the stack. - bool gc_on_transitions = GC_ON_TRANSITIONS (FALSE); - - StackWalkAction result = thread->StackWalkFrames ( - (PSTACKWALKFRAMESCALLBACK)stack_walk_callback, - stack_contents, - ALLOW_ASYNC_STACK_WALK | FUNCTIONSONLY | HANDLESKIPPEDFRAMES | ALLOW_INVALID_OBJECTS); - - GC_ON_TRANSITIONS (gc_on_transitions); - return ((result == SWA_DONE) || (result == SWA_CONTINUE)); + __debugbreak(); + return false; } // The thread store lock must already be held by the thread before this function @@ -97,44 +46,6 @@ walk_managed_stack_for_threads ( ep_rt_thread_handle_t sampling_thread, EventPipeEvent *sampling_event) { - STATIC_CONTRACT_NOTHROW; - EP_ASSERT (sampling_thread != NULL); - - Thread *target_thread = NULL; - - EventPipeStackContents stack_contents; - EventPipeStackContents *current_stack_contents; - current_stack_contents = ep_stack_contents_init (&stack_contents); - - EP_ASSERT (current_stack_contents != NULL); - - // Iterate over all managed threads. - // Assumes that the ThreadStoreLock is held because we've suspended all threads. - while ((target_thread = ThreadStore::GetThreadList (target_thread)) != NULL) { - ep_stack_contents_reset (current_stack_contents); - - // Walk the stack and write it out as an event. - if (ep_rt_aot_walk_managed_stack_for_thread (target_thread, current_stack_contents) && !ep_stack_contents_is_empty (current_stack_contents)) { - // Set the payload. If the GC mode on suspension > 0, then the thread was in cooperative mode. - // Even though there are some cases where this is not managed code, we assume it is managed code here. - // If the GC mode on suspension == 0 then the thread was in preemptive mode, which we qualify as external here. - uint32_t payload_data = target_thread->GetGCModeOnSuspension () ? EP_SAMPLE_PROFILER_SAMPLE_TYPE_MANAGED : EP_SAMPLE_PROFILER_SAMPLE_TYPE_EXTERNAL; - - // Write the sample. - ep_write_sample_profile_event ( - sampling_thread, - sampling_event, - target_thread, - current_stack_contents, - (uint8_t *)&payload_data, - sizeof (payload_data)); - } - - // Reset the GC mode. - target_thread->ClearGCModeOnSuspension (); - } - - ep_stack_contents_fini (current_stack_contents); } void @@ -142,23 +53,6 @@ ep_rt_aot_sample_profiler_write_sampling_event_for_threads ( ep_rt_thread_handle_t sampling_thread, EventPipeEvent *sampling_event) { - STATIC_CONTRACT_NOTHROW; - EP_ASSERT (sampling_thread != NULL); - - // Check to see if we can suspend managed execution. - if (ThreadSuspend::SysIsSuspendInProgress () || (ThreadSuspend::GetSuspensionThread () != 0)) - return; - - // Actually suspend managed execution. - ThreadSuspend::SuspendEE (ThreadSuspend::SUSPEND_REASON::SUSPEND_OTHER); - - // Walk all managed threads and capture stacks. - walk_managed_stack_for_threads (sampling_thread, sampling_event); - - // Resume managed execution. - ThreadSuspend::RestartEE (FALSE /* bFinishedGC */, TRUE /* SuspendSucceeded */); - - return; } #endif /* ENABLE_PERFTRACING */ diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h index 1190d51771d60..2c39186d2e44e 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h @@ -2,22 +2,36 @@ #ifndef __EVENTPIPE_RT_AOT_H__ #define __EVENTPIPE_RT_AOT_H__ -#include +#include // For isspace +#include #ifdef ENABLE_PERFTRACING #include #include #include #include -#include "fstream.h" -#include "typestring.h" -#include "clrversion.h" + +// The regdisplay.h, StackFrameIterator.h, and thread.h includes are present only to access the Thread +// class and can be removed if it turns out that the required ep_rt_thread_handle_t can be +// implemented in some manner that doesn't rely on the Thread class. + +#include "gcenv.h" +#include "regdisplay.h" +#include "StackFrameIterator.h" +#include "thread.h" +#include "holder.h" +#include "SpinLock.h" +#ifdef _INC_WINDOWS +#include +#endif +// @TODO - temp, lakshanf. This is not used in NativeAOT +#define STATIC_CONTRACT_NOTHROW #undef EP_INFINITE_WAIT #define EP_INFINITE_WAIT INFINITE #undef EP_GCX_PREEMP_ENTER -#define EP_GCX_PREEMP_ENTER { GCX_PREEMP(); +#define EP_GCX_PREEMP_ENTER { //GCX_PREEMP(); #undef EP_GCX_PREEMP_EXIT #define EP_GCX_PREEMP_EXIT } @@ -589,6 +603,7 @@ _rt_aot_hash_map_free (HASH_MAP_TYPE *hash_map) EP_ASSERT (HASH_MAP_TYPE::table_type_t::s_NoThrow); EP_ASSERT (hash_map != NULL); + // @TODO - LakshanF: 10/21/22 - Need to understand more on value_free_func, specifically how iterator->Value () gets called if (hash_map->table) { if (hash_map->callbacks.value_free_func) { for (typename HASH_MAP_TYPE::table_type_t::Iterator iterator = hash_map->table->Begin (); iterator != hash_map->table->End (); ++iterator) @@ -611,7 +626,7 @@ _rt_aot_hash_map_add ( EP_ASSERT (HASH_MAP_TYPE::table_type_t::s_NoThrow); EP_ASSERT (hash_map != NULL && hash_map->table != NULL); - return hash_map->table->AddNoThrow (typename HASH_MAP_TYPE::table_type_t::element_t (key, value)); + return hash_map->table->Add (typename HASH_MAP_TYPE::table_type_t::element_t (key, value)); } template @@ -1108,31 +1123,19 @@ inline ep_rt_lock_handle_t * ep_rt_aot_config_lock_get (void) { - STATIC_CONTRACT_NOTHROW; - - extern ep_rt_lock_handle_t _ep_rt_aot_config_lock_handle; - return &_ep_rt_aot_config_lock_handle; + // TODO: Implement EventPipe locking for NativeAOT + return nullptr; } static inline const ep_char8_t * -ep_rt_entrypoint_assembly_name_get_utf8 (void) -{ +ep_rt_entrypoint_assembly_name_get_utf8 (void) +{ STATIC_CONTRACT_NOTHROW; - AppDomain *app_domain_ref = nullptr; - Assembly *assembly_ref = nullptr; - - app_domain_ref = GetAppDomain (); - if (app_domain_ref != nullptr) - { - assembly_ref = app_domain_ref->GetRootAssembly (); - if (assembly_ref != nullptr) - { - return reinterpret_cast(assembly_ref->GetSimpleName ()); - } - } + // TODO: Implement EventPipe assembly name - return filename in nativeaot? + __debugbreak(); // fallback to the empty string if we can't get assembly info, e.g., if the runtime is // suspended before an assembly is loaded. @@ -1141,11 +1144,11 @@ ep_rt_entrypoint_assembly_name_get_utf8 (void) static const ep_char8_t * -ep_rt_runtime_version_get_utf8 (void) -{ +ep_rt_runtime_version_get_utf8 (void) { STATIC_CONTRACT_NOTHROW; - return reinterpret_cast(CLR_PRODUCT_VERSION); + // TODO: Find a way to use CoreCLR runtime_version.h here if a more exact version is needed + return reinterpret_cast("8.0.0"); } /* @@ -1218,7 +1221,7 @@ uint32_t ep_rt_atomic_inc_uint32_t (volatile uint32_t *value) { STATIC_CONTRACT_NOTHROW; - return static_cast(InterlockedIncrement ((volatile LONG *)(value))); + return static_cast(PalInterlockedIncrement ((volatile int32_t *)(value))); } static @@ -1227,7 +1230,7 @@ uint32_t ep_rt_atomic_dec_uint32_t (volatile uint32_t *value) { STATIC_CONTRACT_NOTHROW; - return static_cast(InterlockedDecrement ((volatile LONG *)(value))); + return static_cast(PalInterlockedDecrement ((volatile int32_t *)(value))); } static @@ -1236,7 +1239,7 @@ int32_t ep_rt_atomic_inc_int32_t (volatile int32_t *value) { STATIC_CONTRACT_NOTHROW; - return static_cast(InterlockedIncrement ((volatile LONG *)(value))); + return static_cast(PalInterlockedIncrement (value)); } static @@ -1245,7 +1248,7 @@ int32_t ep_rt_atomic_dec_int32_t (volatile int32_t *value) { STATIC_CONTRACT_NOTHROW; - return static_cast(InterlockedDecrement ((volatile LONG *)(value))); + return static_cast(PalInterlockedDecrement (value)); } static @@ -1254,34 +1257,51 @@ int64_t ep_rt_atomic_inc_int64_t (volatile int64_t *value) { STATIC_CONTRACT_NOTHROW; - return static_cast(InterlockedIncrement64 ((volatile LONG64 *)(value))); + + // TODO: Consider replacing with a new PalInterlockedIncrement64 service + int64_t currentValue; + do { + currentValue = *value; + } while (currentValue != PalInterlockedCompareExchange64(value, (currentValue + 1), currentValue)); + + // The current value has been atomically replaced with the incremented value. + return (currentValue + 1); } static inline int64_t -ep_rt_atomic_dec_int64_t (volatile int64_t *value) -{ +ep_rt_atomic_dec_int64_t (volatile int64_t *value) { STATIC_CONTRACT_NOTHROW; - return static_cast(InterlockedDecrement64 ((volatile LONG64 *)(value))); + + // TODO: Consider replacing with a new PalInterlockedDecrement64 service + int64_t currentValue; + do { + currentValue = *value; + } while (currentValue != PalInterlockedCompareExchange64(value, (currentValue - 1), currentValue)); + + // The current value has been atomically replaced with the decremented value. + return (currentValue - 1); } static inline size_t -ep_rt_atomic_compare_exchange_size_t (volatile size_t *target, size_t expected, size_t value) -{ +ep_rt_atomic_compare_exchange_size_t (volatile size_t *target, size_t expected, size_t value) { STATIC_CONTRACT_NOTHROW; - return static_cast(InterlockedCompareExchangeT (target, value, expected)); +#ifdef HOST_64BIT + return static_cast(PalInterlockedCompareExchange64 ((volatile int64_t *)target, (int64_t)value, (int64_t)expected)); +#else + return static_cast(PalInterlockedCompareExchange ((volatile int32_t *)target, (int32_t)value, (int32_t)expected)); +#endif } static inline ep_char8_t * -ep_rt_atomic_compare_exchange_utf8_string (ep_char8_t *volatile *target, ep_char8_t *expected, ep_char8_t *value) -{ +ep_rt_atomic_compare_exchange_utf8_string (ep_char8_t *volatile *target, ep_char8_t *expected, ep_char8_t *value) { STATIC_CONTRACT_NOTHROW; - return static_cast(InterlockedCompareExchangeT (target, value, expected)); + return static_cast(PalInterlockedCompareExchangePointer ((void *volatile *)target, value, expected)); } /* @@ -1296,31 +1316,9 @@ EP_RT_DEFINE_ARRAY_ITERATOR (execution_checkpoint_array, ep_rt_execution_checkpo static void -ep_rt_init (void) +ep_rt_init (void) { - STATIC_CONTRACT_NOTHROW; - - extern ep_rt_lock_handle_t _ep_rt_aot_config_lock_handle; - extern CrstStatic _ep_rt_aot_config_lock; - - _ep_rt_aot_config_lock_handle.lock = &_ep_rt_aot_config_lock; - _ep_rt_aot_config_lock_handle.lock->InitNoThrow (CrstEventPipe, (CrstFlags)(CRST_REENTRANCY | CRST_TAKEN_DURING_SHUTDOWN | CRST_HOST_BREAKABLE)); - - if (CLRConfig::GetConfigValue (CLRConfig::INTERNAL_EventPipeProcNumbers) != 0) { -#ifndef TARGET_UNIX - // setup the windows processor group offset table - uint16_t groups = ::GetActiveProcessorGroupCount (); - extern uint32_t *_ep_rt_aot_proc_group_offsets; - _ep_rt_aot_proc_group_offsets = new (nothrow) uint32_t [groups]; - if (_ep_rt_aot_proc_group_offsets) { - uint32_t procs = 0; - for (uint16_t i = 0; i < procs; ++i) { - _ep_rt_aot_proc_group_offsets [i] = procs; - procs += GetActiveProcessorCount (i); - } - } -#endif - } + // TODO: Implement EventPipe locking for NativeAOT } static @@ -1344,8 +1342,8 @@ inline bool ep_rt_config_acquire (void) { - STATIC_CONTRACT_NOTHROW; - return ep_rt_lock_acquire (ep_rt_aot_config_lock_get ()); + // TODO: Implement EventPipe locking for NativeAOT + return true; } static @@ -1353,8 +1351,8 @@ inline bool ep_rt_config_release (void) { - STATIC_CONTRACT_NOTHROW; - return ep_rt_lock_release (ep_rt_aot_config_lock_get ()); + // TODO: Implement EventPipe locking for NativeAOT + return true; } #ifdef EP_CHECKED_BUILD @@ -1363,8 +1361,8 @@ inline void ep_rt_config_requires_lock_held (void) { - STATIC_CONTRACT_NOTHROW; - ep_rt_lock_requires_lock_held (ep_rt_aot_config_lock_get ()); + // TODO: Implement EventPipe locking for NativeAOT + return; } static @@ -1372,8 +1370,8 @@ inline void ep_rt_config_requires_lock_not_held (void) { - STATIC_CONTRACT_NOTHROW; - ep_rt_lock_requires_lock_not_held (ep_rt_aot_config_lock_get ()); + // TODO: Implement EventPipe locking for NativeAOT + return; } #endif @@ -1398,19 +1396,12 @@ ep_rt_method_get_simple_assembly_name ( size_t name_len) { STATIC_CONTRACT_NOTHROW; - EP_ASSERT (method != NULL); - EP_ASSERT (name != NULL); - const ep_char8_t *assembly_name = method->GetLoaderModule ()->GetAssembly ()->GetSimpleName (); - if (!assembly_name) - return false; + // TODO: Design MethodDesc and method name services if/when needed + __debugbreak(); - size_t assembly_name_len = strlen (assembly_name) + 1; - size_t to_copy = assembly_name_len < name_len ? assembly_name_len : name_len; - memcpy (name, assembly_name, to_copy); - name [to_copy - 1] = 0; + return false; - return true; } static @@ -1420,33 +1411,10 @@ ep_rt_method_get_full_name ( ep_char8_t *name, size_t name_len) { - STATIC_CONTRACT_NOTHROW; - EP_ASSERT (method != NULL); - EP_ASSERT (name != NULL); - - bool result = true; - EX_TRY - { - SString method_name; - - TypeString::AppendMethodInternal (method_name, method, TypeString::FormatNamespace | TypeString::FormatSignature); - const ep_char8_t *method_name_utf8 = method_name.GetUTF8 (); - if (method_name_utf8) { - size_t method_name_utf8_len = strlen (method_name_utf8) + 1; - size_t to_copy = method_name_utf8_len < name_len ? method_name_utf8_len : name_len; - memcpy (name, method_name_utf8, to_copy); - name [to_copy - 1] = 0; - } else { - result = false; - } - } - EX_CATCH - { - result = false; - } - EX_END_CATCH(SwallowAllExceptions); + // TODO: Design MethodDesc and method name services if/when needed + __debugbreak(); - return result; + return false; } static @@ -1456,11 +1424,25 @@ ep_rt_provider_config_init (EventPipeProviderConfiguration *provider_config) { STATIC_CONTRACT_NOTHROW; - if (!ep_rt_utf8_string_compare (ep_config_get_rundown_provider_name_utf8 (), ep_provider_config_get_provider_name (provider_config))) { - MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context.EventPipeProvider.Level = (UCHAR) ep_provider_config_get_logging_level (provider_config); - MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context.EventPipeProvider.EnabledKeywordsBitmask = ep_provider_config_get_keywords (provider_config); - MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context.EventPipeProvider.IsEnabled = true; - } + // TODO: MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context is not available in NativeAOT + +/** + // Mono implementation + if (!ep_rt_utf8_string_compare (ep_config_get_rundown_provider_name_utf8 (), ep_provider_config_get_provider_name (provider_config))) { + MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_EVENTPIPE_Context.Level = (uint8_t)ep_provider_config_get_logging_level (provider_config); + MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_EVENTPIPE_Context.EnabledKeywordsBitmask = ep_provider_config_get_keywords (provider_config); + MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_EVENTPIPE_Context.IsEnabled = true; + } + + // CoreCLR + if (!ep_rt_utf8_string_compare (ep_config_get_rundown_provider_name_utf8 (), ep_provider_config_get_provider_name (provider_config))) { + MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context.EventPipeProvider.Level = (UCHAR) ep_provider_config_get_logging_level (provider_config); + MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context.EventPipeProvider.EnabledKeywordsBitmask = ep_provider_config_get_keywords (provider_config); + MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context.EventPipeProvider.IsEnabled = true; + } +*/ + + //__debugbreak(); } // This function is auto-generated from /src/scripts/genEventPipe.py @@ -1474,14 +1456,8 @@ static void ep_rt_init_providers_and_events (void) { - STATIC_CONTRACT_NOTHROW; - - EX_TRY - { - InitProvidersAndEvents (); - } - EX_CATCH {} - EX_END_CATCH(SwallowAllExceptions); + // TODO: auto-generated fn, no op for now + // InitProvidersAndEvents (); } static @@ -1490,10 +1466,8 @@ bool ep_rt_providers_validate_all_disabled (void) { STATIC_CONTRACT_NOTHROW; - - return (!MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context.EventPipeProvider.IsEnabled && - !MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_DOTNET_Context.EventPipeProvider.IsEnabled && - !MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context.EventPipeProvider.IsEnabled); + // TODO: MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context and MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_DOTNET_Context are not available in NativeAOT + return true; } static @@ -1519,19 +1493,14 @@ ep_rt_provider_invoke_callback ( STATIC_CONTRACT_NOTHROW; EP_ASSERT (callback_func != NULL); - EX_TRY - { - (*callback_func)( - source_id, - is_enabled, - level, - match_any_keywords, - match_all_keywords, - filter_data, - callback_data); - } - EX_CATCH {} - EX_END_CATCH(SwallowAllExceptions); + (*callback_func)( + source_id, + is_enabled, + level, + match_any_keywords, + match_all_keywords, + filter_data, + callback_data); } /* @@ -1592,8 +1561,8 @@ ep_rt_provider_list_find_by_name ( // The provider list should be non-NULL, but can be NULL on shutdown. if (list) { - SList> *provider_list = list->list; - SListElem *element = provider_list->GetHead (); + SList_EP> *provider_list = list->list; + SListElem_EP *element = provider_list->GetHead (); while (element) { EventPipeProvider *provider = element->GetValue (); if (ep_rt_utf8_string_compare (ep_provider_get_provider_name (element->GetValue ()), name) == 0) @@ -1618,8 +1587,11 @@ inline bool ep_rt_config_value_get_enable (void) { - STATIC_CONTRACT_NOTHROW; - return CLRConfig::GetConfigValue (CLRConfig::INTERNAL_EnableEventPipe) != 0; + // TODO: EventPipe Configuration values - RhConfig? + // (CLRConfig::INTERNAL_EnableEventPipe) != 0 + // If EventPipe environment variables are specified, parse them and start a session. + // TODO: Not start a session for now + return false; } static @@ -1628,8 +1600,11 @@ ep_char8_t * ep_rt_config_value_get_config (void) { STATIC_CONTRACT_NOTHROW; - CLRConfigStringHolder value(CLRConfig::GetConfigValue (CLRConfig::INTERNAL_EventPipeConfig)); - return ep_rt_utf16_to_utf8_string (reinterpret_cast(value.GetValue ()), -1); + // TODO: EventPipe Configuration values - RhConfig? + // (CLRConfig::INTERNAL_EventPipeConfig) + __debugbreak(); + return nullptr; +// return ep_rt_utf16_to_utf8_string (reinterpret_cast(value.GetValue ()), -1); } static @@ -1638,8 +1613,10 @@ ep_char8_t * ep_rt_config_value_get_output_path (void) { STATIC_CONTRACT_NOTHROW; - CLRConfigStringHolder value(CLRConfig::GetConfigValue (CLRConfig::INTERNAL_EventPipeOutputPath)); - return ep_rt_utf16_to_utf8_string (reinterpret_cast(value.GetValue ()), -1); + // TODO: EventPipe Configuration values - RhConfig? + // (CLRConfig::INTERNAL_EventPipeOutputPath) + __debugbreak(); + return nullptr; } static @@ -1648,7 +1625,10 @@ uint32_t ep_rt_config_value_get_circular_mb (void) { STATIC_CONTRACT_NOTHROW; - return CLRConfig::GetConfigValue (CLRConfig::INTERNAL_EventPipeCircularMB); + // TODO: EventPipe Configuration values - RhConfig? + // (CLRConfig::INTERNAL_EventPipeCircularMB) + __debugbreak(); + return 0; } static @@ -1657,7 +1637,10 @@ bool ep_rt_config_value_get_output_streaming (void) { STATIC_CONTRACT_NOTHROW; - return CLRConfig::GetConfigValue (CLRConfig::INTERNAL_EventPipeOutputStreaming) != 0; + // TODO: EventPipe Configuration values - RhConfig? + // (CLRConfig::INTERNAL_EventPipeOutputStreaming) + __debugbreak(); + return false; } /* @@ -1682,14 +1665,7 @@ inline void ep_rt_notify_profiler_provider_created (EventPipeProvider *provider) { - STATIC_CONTRACT_NOTHROW; - -#ifndef DACCESS_COMPILE - // Let the profiler know the provider has been created so it can register if it wants to - BEGIN_PROFILER_CALLBACK (CORProfilerTrackEventPipe ()); - (&g_profControlBlock)->EventPipeProviderCreated (provider); - END_PROFILER_CALLBACK (); -#endif // DACCESS_COMPILE + // Following mono's path of no-op } /* @@ -1707,9 +1683,9 @@ ep_rt_session_provider_list_find_by_name ( { STATIC_CONTRACT_NOTHROW; - SList> *provider_list = list->list; + SList_EP> *provider_list = list->list; EventPipeSessionProvider *session_provider = NULL; - SListElem *element = provider_list->GetHead (); + SListElem_EP *element = provider_list->GetHead (); while (element) { EventPipeSessionProvider *candidate = element->GetValue (); if (ep_rt_utf8_string_compare (ep_session_provider_get_provider_name (candidate), name) == 0) { @@ -1801,15 +1777,11 @@ ep_rt_wait_event_alloc ( wait_event->event = new (nothrow) CLREventStatic (); if (wait_event->event) { - EX_TRY - { - if (manual) - wait_event->event->CreateManualEvent (initial); - else - wait_event->event->CreateAutoEvent (initial); - } - EX_CATCH {} - EX_END_CATCH(SwallowAllExceptions); + // NativeAOT has the NoThrow versions + if (manual) + wait_event->event->CreateManualEventNoThrow (initial); + else + wait_event->event->CreateAutoEventNoThrow (initial); } } @@ -1830,8 +1802,8 @@ ep_rt_wait_event_free (ep_rt_wait_event_handle_t *wait_event) static inline bool -ep_rt_wait_event_set (ep_rt_wait_event_handle_t *wait_event) -{ +ep_rt_wait_event_set (ep_rt_wait_event_handle_t *wait_event) +{ STATIC_CONTRACT_NOTHROW; EP_ASSERT (wait_event != NULL && wait_event->event != NULL); @@ -1843,40 +1815,32 @@ int32_t ep_rt_wait_event_wait ( ep_rt_wait_event_handle_t *wait_event, uint32_t timeout, - bool alertable) -{ + bool alertable) +{ STATIC_CONTRACT_NOTHROW; EP_ASSERT (wait_event != NULL && wait_event->event != NULL); - int32_t result; - EX_TRY - { - result = wait_event->event->Wait (timeout, alertable); - } - EX_CATCH - { - result = -1; - } - EX_END_CATCH(SwallowAllExceptions); - return result; + return wait_event->event->Wait (timeout, alertable); } static inline EventPipeWaitHandle -ep_rt_wait_event_get_wait_handle (ep_rt_wait_event_handle_t *wait_event) -{ +ep_rt_wait_event_get_wait_handle (ep_rt_wait_event_handle_t *wait_event) +{ STATIC_CONTRACT_NOTHROW; EP_ASSERT (wait_event != NULL && wait_event->event != NULL); - return reinterpret_cast(wait_event->event->GetHandleUNHOSTED ()); + // TODO: NativeAOT CLREventStatic doesn't have GetHandleUNHOSTED + __debugbreak(); + return 0; } static inline bool -ep_rt_wait_event_is_valid (ep_rt_wait_event_handle_t *wait_event) -{ +ep_rt_wait_event_is_valid (ep_rt_wait_event_handle_t *wait_event) +{ STATIC_CONTRACT_NOTHROW; if (wait_event == NULL || wait_event->event == NULL) @@ -1895,7 +1859,7 @@ int ep_rt_get_last_error (void) { STATIC_CONTRACT_NOTHROW; - return ::GetLastError (); + return PalGetLastError(); } static @@ -1904,7 +1868,10 @@ bool ep_rt_process_detach (void) { STATIC_CONTRACT_NOTHROW; - return (bool)g_fProcessDetach; + // TODO: Does NativeAot have the concept of process detach + // __debugbreak(); + + return false; } static @@ -1913,7 +1880,10 @@ bool ep_rt_process_shutdown (void) { STATIC_CONTRACT_NOTHROW; - return (bool)g_fEEShutDown; + // TODO: Does NativeAot have the concept of process shutdown + //__debugbreak(); + + return false; } static @@ -1927,7 +1897,35 @@ ep_rt_create_activity_id ( EP_ASSERT (activity_id != NULL); EP_ASSERT (activity_id_len == EP_ACTIVITY_ID_SIZE); - CoCreateGuid (reinterpret_cast(activity_id)); + // TODO: Implement a way to generate a real Guid + // CoCreateGuid (reinterpret_cast(activity_id)); + + // TODO: Using roughly Mono's implementation but Mono randomly generates this, hardcoding for now + uint8_t data1[] = {0x67,0xac,0x33,0xf1,0x8d,0xed,0x41,0x01,0xb4,0x26,0xc9,0xb7,0x94,0x35,0xf7,0x8a}; + memcpy (activity_id, data1, EP_ACTIVITY_ID_SIZE); + + const uint16_t version_mask = 0xF000; + const uint16_t random_guid_version = 0x4000; + const uint8_t clock_seq_hi_and_reserved_mask = 0xC0; + const uint8_t clock_seq_hi_and_reserved_value = 0x80; + + // Modify bits indicating the type of the GUID + uint8_t *activity_id_c = activity_id + sizeof (uint32_t) + sizeof (uint16_t); + uint8_t *activity_id_d = activity_id + sizeof (uint32_t) + sizeof (uint16_t) + sizeof (uint16_t); + + uint16_t c; + memcpy (&c, activity_id_c, sizeof (c)); + + uint8_t d; + memcpy (&d, activity_id_d, sizeof (d)); + + // time_hi_and_version + c = ((c & ~version_mask) | random_guid_version); + // clock_seq_hi_and_reserved + d = ((d & ~clock_seq_hi_and_reserved_mask) | clock_seq_hi_and_reserved_value); + + memcpy (activity_id_c, &c, sizeof (c)); + memcpy (activity_id_d, &d, sizeof (d)); } static @@ -1936,7 +1934,10 @@ bool ep_rt_is_running (void) { STATIC_CONTRACT_NOTHROW; - return (bool)g_fEEStarted; + // TODO: Does NativeAot have the concept of EEStarted + __debugbreak(); + + return false; } static @@ -1947,11 +1948,9 @@ ep_rt_execute_rundown (ep_rt_execution_checkpoint_array_t *execution_checkpoints STATIC_CONTRACT_NOTHROW; //TODO: Write execution checkpoint rundown events. - if (CLRConfig::GetConfigValue (CLRConfig::INTERNAL_EventPipeRundown) > 0) { - // Ask the runtime to emit rundown events. - if (g_fEEStarted && !g_fEEShutDown) - ETW::EnumerationLog::EndRundown (); - } + // TODO: EventPipe Configuration values - RhConfig? + // (CLRConfig::INTERNAL_EventPipeCircularMB) + __debugbreak(); } /* @@ -1978,21 +1977,22 @@ ep_rt_execute_rundown (ep_rt_execution_checkpoint_array_t *execution_checkpoints * PAL. */ -typedef struct _rt_aot_thread_params_internal_t { - ep_rt_thread_params_t thread_params; -} rt_aot_thread_params_internal_t; - #undef EP_RT_DEFINE_THREAD_FUNC -#define EP_RT_DEFINE_THREAD_FUNC(name) static ep_rt_thread_start_func_return_t WINAPI name (LPVOID data) +#define EP_RT_DEFINE_THREAD_FUNC(name) static ep_rt_thread_start_func_return_t __stdcall name (void *data) -EP_RT_DEFINE_THREAD_FUNC (ep_rt_thread_aot_start_func) +EP_RT_DEFINE_THREAD_FUNC (ep_rt_thread_aot_start_session_or_sampling_thread) { STATIC_CONTRACT_NOTHROW; - rt_aot_thread_params_internal_t *thread_params = reinterpret_cast(data); - DWORD result = thread_params->thread_params.thread_func (thread_params); - if (thread_params->thread_params.thread) - ::DestroyThread (thread_params->thread_params.thread); + ep_rt_thread_params_t* thread_params = reinterpret_cast(data); + + // TODO: Implement thread creation/management if needed. + // The session and sampling threads both assert that the incoming thread handle is + // non-null, but do not necessarily rely on it otherwise; just pass a meaningless non-null + // value until testing shows that a meaningful value is needed. + thread_params->thread = reinterpret_cast(1); + + size_t result = thread_params->thread_func (thread_params); delete thread_params; return result; } @@ -2008,58 +2008,78 @@ ep_rt_thread_create ( STATIC_CONTRACT_NOTHROW; EP_ASSERT (thread_func != NULL); - bool result = false; + // TODO: Fill in the outgoing id if any callers ever need it + if (id) + *reinterpret_cast(id) = 0xffffffff; - EX_TRY + switch (thread_type) { - if (thread_type == EP_THREAD_TYPE_SERVER) - { - DWORD thread_id = 0; - HANDLE server_thread = ::CreateThread (nullptr, 0, reinterpret_cast(thread_func), nullptr, 0, &thread_id); - if (server_thread != NULL) - { - if (id) - { - *reinterpret_cast(id) = thread_id; - } - ::CloseHandle (server_thread); - result = true; - } - } - else if (thread_type == EP_THREAD_TYPE_SESSION || thread_type == EP_THREAD_TYPE_SAMPLING) - { - rt_aot_thread_params_internal_t *thread_params = new (nothrow) rt_aot_thread_params_internal_t (); - if (thread_params) - { - thread_params->thread_params.thread_type = thread_type; - thread_params->thread_params.thread = SetupUnstartedThread (); - thread_params->thread_params.thread_func = reinterpret_cast(thread_func); - thread_params->thread_params.thread_params = params; - - if (thread_params->thread_params.thread->CreateNewThread (0, ep_rt_thread_aot_start_func, thread_params)) - { - if (id) - { - *reinterpret_cast(id) = thread_params->thread_params.thread->GetThreadId (); - } - thread_params->thread_params.thread->SetBackground (TRUE); - thread_params->thread_params.thread->StartThread (); - result = true; - } - else - { - delete thread_params; - } - } + default: + return false; + + case EP_THREAD_TYPE_SERVER: + // Match CoreCLR and hardcode a null thread context in this case. + return PalStartEventPipeHelperThread(reinterpret_cast(thread_func), NULL); + + case EP_THREAD_TYPE_SESSION: + case EP_THREAD_TYPE_SAMPLING: + ep_rt_thread_params_t* thread_params = new (nothrow) ep_rt_thread_params_t (); + if (!thread_params) + return false; + + thread_params->thread_type = thread_type; + thread_params->thread_func = reinterpret_cast(thread_func); + thread_params->thread_params = params; + if (!PalStartEventPipeHelperThread(reinterpret_cast(ep_rt_thread_aot_start_session_or_sampling_thread), thread_params)) { + delete thread_params; + return false; } + + return true; } - EX_CATCH - { - result = false; + + + // Mono implementation +/** + rt_mono_thread_params_internal_t *thread_params = g_new0 (rt_mono_thread_params_internal_t, 1); + if (thread_params) { + thread_params->thread_params.thread_type = thread_type; + thread_params->thread_params.thread_func = (ep_rt_thread_start_func)thread_func; + thread_params->thread_params.thread_params = params; + thread_params->background_thread = true; + return (mono_thread_platform_create_thread (ep_rt_thread_mono_start_func, thread_params, NULL, (ep_rt_thread_id_t *)id) == TRUE) ? true : false; } - EX_END_CATCH(SwallowAllExceptions); - return result; + return false; + + * */ + + // CoreCLR implementation + + // if (thread_params) { + // thread_params->thread_params.thread_type = thread_type; + // if (thread_type == EP_THREAD_TYPE_SESSION || thread_type == EP_THREAD_TYPE_SAMPLING) { + // thread_params->thread_params.thread = SetupUnstartedThread (); + // thread_params->thread_params.thread_func = reinterpret_cast(thread_func); + // thread_params->thread_params.thread_params = params; + // if (thread_params->thread_params.thread->CreateNewThread (0, ep_rt_thread_aot_start_func, thread_params)) { + // thread_params->thread_params.thread->SetBackground (TRUE); + // thread_params->thread_params.thread->StartThread (); + // if (id) + // *reinterpret_cast(id) = thread_params->thread_params.thread->GetThreadId (); + // result = true; + // } + // } else if (thread_type == EP_THREAD_TYPE_SERVER) { + // DWORD thread_id = 0; + // HANDLE server_thread = ::CreateThread (nullptr, 0, reinterpret_cast(thread_func), nullptr, 0, &thread_id); + // if (server_thread != NULL) { + // ::CloseHandle (server_thread); + // if (id) + // *reinterpret_cast(id) = thread_id; + // result = true; + // } + // } + // } } static @@ -2067,22 +2087,19 @@ inline void ep_rt_set_server_name(void) { - ::SetThreadName(GetCurrentThread(), W(".NET EventPipe")); + // TODO: Need to set name for the thread + // ::SetThreadName(GetCurrentThread(), W(".NET EventPipe")); + //__debugbreak(); } + static inline void ep_rt_thread_sleep (uint64_t ns) { STATIC_CONTRACT_NOTHROW; - -#ifdef TARGET_UNIX - PAL_nanosleep (ns); -#else //TARGET_UNIX - const uint32_t NUM_NANOSECONDS_IN_1_MS = 1000000; - ClrSleepEx (static_cast(ns / NUM_NANOSECONDS_IN_1_MS), FALSE); -#endif //TARGET_UNIX + PalSleep(static_cast(ns/1000000)); } static @@ -2104,9 +2121,10 @@ ep_rt_current_processor_get_number (void) #ifndef TARGET_UNIX extern uint32_t *_ep_rt_aot_proc_group_offsets; if (_ep_rt_aot_proc_group_offsets) { - PROCESSOR_NUMBER proc; - GetCurrentProcessorNumberEx (&proc); - return _ep_rt_aot_proc_group_offsets [proc.Group] + proc.Number; + // PROCESSOR_NUMBER proc; + // GetCurrentProcessorNumberEx (&proc); + // return _ep_rt_aot_proc_group_offsets [proc.Group] + proc.Number; + __debugbreak(); } #endif return 0xFFFFFFFF; @@ -2118,10 +2136,14 @@ uint32_t ep_rt_processors_get_count (void) { STATIC_CONTRACT_NOTHROW; - +#ifdef _INC_WINDOWS SYSTEM_INFO sys_info = {}; GetSystemInfo (&sys_info); return static_cast(sys_info.dwNumberOfProcessors); +#else + __debugbreak(); + return 0xffff; +#endif } static @@ -2132,7 +2154,9 @@ ep_rt_current_thread_get_id (void) STATIC_CONTRACT_NOTHROW; #ifdef TARGET_UNIX - return static_cast(::PAL_GetCurrentOSThreadId ()); + // TODO: AOT doesn't have PAL_GetCurrentOSThreadId, as CoreCLR does. + __debugbreak(); + return static_cast(0); #else return static_cast(::GetCurrentThreadId ()); #endif @@ -2144,12 +2168,7 @@ int64_t ep_rt_perf_counter_query (void) { STATIC_CONTRACT_NOTHROW; - - LARGE_INTEGER value; - if (QueryPerformanceCounter (&value)) - return static_cast(value.QuadPart); - else - return 0; + return (int64_t)PalQueryPerformanceCounter(); } static @@ -2158,12 +2177,7 @@ int64_t ep_rt_perf_frequency_query (void) { STATIC_CONTRACT_NOTHROW; - - LARGE_INTEGER value; - if (QueryPerformanceFrequency (&value)) - return static_cast(value.QuadPart); - else - return 0; + return (int64_t)PalQueryPerformanceFrequency(); } static @@ -2173,20 +2187,26 @@ ep_rt_system_time_get (EventPipeSystemTime *system_time) { STATIC_CONTRACT_NOTHROW; +#ifdef _INC_WINDOWS SYSTEMTIME value; GetSystemTime (&value); EP_ASSERT(system_time != NULL); ep_system_time_set ( - system_time, - value.wYear, - value.wMonth, - value.wDayOfWeek, - value.wDay, - value.wHour, - value.wMinute, - value.wSecond, - value.wMilliseconds); + system_time, + value.wYear, + value.wMonth, + value.wDayOfWeek, + value.wDay, + value.wHour, + value.wMinute, + value.wSecond, + value.wMilliseconds); +#else + // TODO: Get System time + __debugbreak(); +#endif + } static @@ -2207,7 +2227,9 @@ int32_t ep_rt_system_get_alloc_granularity (void) { STATIC_CONTRACT_NOTHROW; - return static_cast(g_SystemInfo.dwAllocationGranularity); + // return static_cast(g_SystemInfo.dwAllocationGranularity); + //__debugbreak(); + return 0x10000;//0xffff; } static @@ -2230,14 +2252,10 @@ ep_rt_file_open_write (const ep_char8_t *path) ep_char16_t *path_utf16 = ep_rt_utf8_to_utf16le_string (path, -1); ep_return_null_if_nok (path_utf16 != NULL); - CFileStream *file_stream = new (nothrow) CFileStream (); - if (file_stream && FAILED (file_stream->OpenForWrite (reinterpret_cast(path_utf16)))) { - delete file_stream; - file_stream = NULL; - } + // TODO: Find out the way to open a file in native + __debugbreak(); - ep_rt_utf16_string_free (path_utf16); - return static_cast(file_stream); + return 0; } static @@ -2247,9 +2265,8 @@ ep_rt_file_close (ep_rt_file_handle_t file_handle) { STATIC_CONTRACT_NOTHROW; - // Closed in destructor. - if (file_handle) - delete file_handle; + // TODO: Find out the way to close a file in native + __debugbreak(); return true; } @@ -2265,12 +2282,10 @@ ep_rt_file_write ( STATIC_CONTRACT_NOTHROW; EP_ASSERT (buffer != NULL); - ep_return_false_if_nok (file_handle != NULL); - - ULONG out_count; - HRESULT result = reinterpret_cast(file_handle)->Write (buffer, bytes_to_write, &out_count); - *bytes_written = static_cast(out_count); - return result == S_OK; + // TODO: Find out the way to write to a file in native + __debugbreak(); + + return false; } static @@ -2279,7 +2294,7 @@ uint8_t * ep_rt_valloc0 (size_t buffer_size) { STATIC_CONTRACT_NOTHROW; - return reinterpret_cast(ClrVirtualAlloc (NULL, buffer_size, MEM_COMMIT, PAGE_READWRITE)); + return reinterpret_cast(PalVirtualAlloc (NULL, buffer_size, MEM_COMMIT, PAGE_READWRITE)); } static @@ -2292,7 +2307,7 @@ ep_rt_vfree ( STATIC_CONTRACT_NOTHROW; if (buffer) - ClrVirtualFree (buffer, 0, MEM_RELEASE); + PalVirtualFree (buffer, 0, MEM_RELEASE); } static @@ -2318,15 +2333,16 @@ ep_rt_os_environment_get_utf16 (ep_rt_env_array_utf16_t *env_array) STATIC_CONTRACT_NOTHROW; EP_ASSERT (env_array != NULL); - LPWSTR envs = GetEnvironmentStringsW (); - if (envs) { - LPWSTR next = envs; - while (*next) { - ep_rt_env_array_utf16_append (env_array, ep_rt_utf16_string_dup (reinterpret_cast(next))); - next += ep_rt_utf16_string_len (reinterpret_cast(next)) + 1; - } - FreeEnvironmentStringsW (envs); - } + // LPWSTR envs = GetEnvironmentStringsW (); + // if (envs) { + // LPWSTR next = envs; + // while (*next) { + // ep_rt_env_array_utf16_append (env_array, ep_rt_utf16_string_dup (reinterpret_cast(next))); + // next += ep_rt_utf16_string_len (reinterpret_cast(next)) + 1; + // } + // FreeEnvironmentStringsW (envs); + // } + __debugbreak(); } /* @@ -2340,18 +2356,7 @@ ep_rt_lock_acquire (ep_rt_lock_handle_t *lock) STATIC_CONTRACT_NOTHROW; bool result = true; - EX_TRY - { - if (lock) { - CrstBase::CrstHolderWithState holder (lock->lock); - holder.SuppressRelease (); - } - } - EX_CATCH - { - result = false; - } - EX_END_CATCH(SwallowAllExceptions); + // TODO: Implement EventPipe locking for NativeAOT return result; } @@ -2363,18 +2368,7 @@ ep_rt_lock_release (ep_rt_lock_handle_t *lock) STATIC_CONTRACT_NOTHROW; bool result = true; - EX_TRY - { - if (lock) { - CrstBase::UnsafeCrstInverseHolder holder (lock->lock); - holder.SuppressRelease (); - } - } - EX_CATCH - { - result = false; - } - EX_END_CATCH(SwallowAllExceptions); + // TODO: Implement EventPipe locking for NativeAOT return result; } @@ -2385,6 +2379,7 @@ inline void ep_rt_lock_requires_lock_held (const ep_rt_lock_handle_t *lock) { + STATIC_CONTRACT_NOTHROW; EP_ASSERT (((ep_rt_lock_handle_t *)lock)->lock->OwnedByCurrentThread ()); } @@ -2409,13 +2404,7 @@ ep_rt_spin_lock_alloc (ep_rt_spin_lock_handle_t *spin_lock) { STATIC_CONTRACT_NOTHROW; - EX_TRY - { - spin_lock->lock = new (nothrow) SpinLock (); - spin_lock->lock->Init (LOCK_TYPE_DEFAULT); - } - EX_CATCH {} - EX_END_CATCH(SwallowAllExceptions); + spin_lock->lock = new (nothrow) SpinLock (); } static @@ -2439,7 +2428,8 @@ ep_rt_spin_lock_acquire (ep_rt_spin_lock_handle_t *spin_lock) STATIC_CONTRACT_NOTHROW; EP_ASSERT (ep_rt_spin_lock_is_valid (spin_lock)); - SpinLock::AcquireLock (spin_lock->lock); + // TODO: Implement locking (maybe by making the manual Lock and Unlock functions public) + // SpinLock::Lock (*(spin_lock->lock)); return true; } @@ -2451,7 +2441,8 @@ ep_rt_spin_lock_release (ep_rt_spin_lock_handle_t *spin_lock) STATIC_CONTRACT_NOTHROW; EP_ASSERT (ep_rt_spin_lock_is_valid (spin_lock)); - SpinLock::ReleaseLock (spin_lock->lock); + // TODO: Implement locking (maybe by making the manual Lock and Unlock functions public) + // SpinLock::Unlock (*(spin_lock->lock)); return true; } @@ -2463,7 +2454,7 @@ ep_rt_spin_lock_requires_lock_held (const ep_rt_spin_lock_handle_t *spin_lock) { STATIC_CONTRACT_NOTHROW; EP_ASSERT (ep_rt_spin_lock_is_valid (spin_lock)); - EP_ASSERT (spin_lock->lock->OwnedByCurrentThread ()); + } static @@ -2472,7 +2463,7 @@ void ep_rt_spin_lock_requires_lock_not_held (const ep_rt_spin_lock_handle_t *spin_lock) { STATIC_CONTRACT_NOTHROW; - EP_ASSERT (spin_lock->lock == NULL || !spin_lock->lock->OwnedByCurrentThread ()); + } #endif @@ -2543,7 +2534,11 @@ ep_rt_utf8_string_dup (const ep_char8_t *str) if (!str) return NULL; +#ifdef TARGET_UNIX + return strdup (str); +#else return _strdup (str); +#endif } static @@ -2570,7 +2565,11 @@ ep_rt_utf8_string_strtok ( ep_char8_t **context) { STATIC_CONTRACT_NOTHROW; +#ifdef TARGET_UNIX + return strtok_r (str, delimiter, context); +#else return strtok_s (str, delimiter, context); +#endif } // STATIC_CONTRACT_NOTHROW @@ -2624,24 +2623,21 @@ ep_rt_utf8_to_utf16le_string ( if (!str) return NULL; - COUNT_T len_utf16 = WszMultiByteToWideChar (CP_UTF8, 0, str, static_cast(len), 0, 0); - if (len_utf16 == 0) + // TODO: Implementation would just use strlen and malloc to make a new buffer, and would then copy the string chars one by one + size_t len_utf8 = strlen(str); + if (len_utf8 == 0) return NULL; - if (static_cast(len) != -1) - len_utf16 += 1; - - ep_char16_t *str_utf16 = reinterpret_cast(malloc (len_utf16 * sizeof (ep_char16_t))); + ep_char16_t *str_utf16 = reinterpret_cast(malloc ((len_utf8 + 1) * sizeof (ep_char16_t))); if (!str_utf16) return NULL; - len_utf16 = WszMultiByteToWideChar (CP_UTF8, 0, str, static_cast(len), reinterpret_cast(str_utf16), len_utf16); - if (len_utf16 == 0) { - free (str_utf16); - return NULL; + for (size_t i = 0; i < len_utf8; i++) + { + str_utf16[i] = str[i]; } - str_utf16 [len_utf16 - 1] = 0; + str_utf16[len_utf8] = 0; return str_utf16; } @@ -2694,25 +2690,24 @@ ep_rt_utf16_to_utf8_string ( if (!str) return NULL; + + // TODO: Temp implementation that is the reverse of ep_rt_utf8_to_utf16le_string + size_t len_utf16 = len; + if(len_utf16 == -1) + { + len_utf16 = ep_rt_utf16_string_len (str); + } - COUNT_T size_utf8 = WszWideCharToMultiByte (CP_UTF8, 0, reinterpret_cast(str), static_cast(len), NULL, 0, NULL, NULL); - if (size_utf8 == 0) - return NULL; - - if (static_cast(len) != -1) - size_utf8 += 1; - - ep_char8_t *str_utf8 = reinterpret_cast(malloc (size_utf8)); + ep_char8_t *str_utf8 = reinterpret_cast(malloc ((len_utf16 + 1) * sizeof (ep_char8_t))); if (!str_utf8) return NULL; - size_utf8 = WszWideCharToMultiByte (CP_UTF8, 0, reinterpret_cast(str), static_cast(len), reinterpret_cast(str_utf8), size_utf8, NULL, NULL); - if (size_utf8 == 0) { - free (str_utf8); - return NULL; + for (size_t i = 0; i < len_utf16; i++) + { + str_utf8[i] = (char)str[i]; } - str_utf8 [size_utf8 - 1] = 0; + str_utf8[len_utf16] = 0; return str_utf8; } @@ -2752,9 +2747,14 @@ static const ep_char8_t * ep_rt_diagnostics_command_line_get (void) { + STATIC_CONTRACT_NOTHROW; - // In aot, this value can change over time, specifically before vs after suspension in diagnostics server. + // TODO: revisit commandline for AOT + // return reinterpret_cast(::GetCommandLineA()); + + + // In coreclr, this value can change over time, specifically before vs after suspension in diagnostics server. // The host initializes the runtime in two phases, init and exec assembly. On non-Windows platforms the commandline returned by the runtime // is different during each phase. We suspend during init where the runtime has populated the commandline with a // mock value (the full path of the executing assembly) and the actual value isn't populated till the exec assembly phase. @@ -2766,18 +2766,19 @@ ep_rt_diagnostics_command_line_get (void) extern ep_char8_t *volatile _ep_rt_aot_diagnostics_cmd_line; ep_char8_t *old_cmd_line = _ep_rt_aot_diagnostics_cmd_line; - ep_char8_t *new_cmd_line = ep_rt_utf16_to_utf8_string (reinterpret_cast(GetCommandLineForDiagnostics ()), -1); - if (old_cmd_line && ep_rt_utf8_string_compare (old_cmd_line, new_cmd_line) == 0) { - // same as old, so free the new one - ep_rt_utf8_string_free (new_cmd_line); - } else { - // attempt an update, and give up if you lose the race - if (ep_rt_atomic_compare_exchange_utf8_string (&_ep_rt_aot_diagnostics_cmd_line, old_cmd_line, new_cmd_line) != old_cmd_line) { - ep_rt_utf8_string_free (new_cmd_line); - } - // NOTE: If there was a value we purposefully leak it since it may still be in use. - // This leak is *small* (length of the command line) and bounded (should only happen once) - } + + // ep_char8_t *new_cmd_line = ep_rt_utf16_to_utf8_string (reinterpret_cast(GetCommandLineForDiagnostics ()), -1); + // __debugbreak(); + // ep_char8_t *new_cmd_line = NULL; + // if (old_cmd_line && ep_rt_utf8_string_compare (old_cmd_line, new_cmd_line) == 0) { + // // same as old, so free the new one + // ep_rt_utf8_string_free (new_cmd_line); + // } else { + // // attempt an update, and give up if you lose the race + // if (ep_rt_atomic_compare_exchange_utf8_string (&_ep_rt_aot_diagnostics_cmd_line, old_cmd_line, new_cmd_line) != old_cmd_line) { + // ep_rt_utf8_string_free (new_cmd_line); + // } + // } return _ep_rt_aot_diagnostics_cmd_line; } @@ -2810,14 +2811,14 @@ thread_holder_free_func (EventPipeThreadHolder * thread_holder) } } -class EventPipeCoreCLRThreadHolderTLS { +class EventPipeAotThreadHolderTLS { public: - EventPipeCoreCLRThreadHolderTLS () + EventPipeAotThreadHolderTLS () { STATIC_CONTRACT_NOTHROW; } - ~EventPipeCoreCLRThreadHolderTLS () + ~EventPipeAotThreadHolderTLS () { STATIC_CONTRACT_NOTHROW; @@ -2847,7 +2848,7 @@ class EventPipeCoreCLRThreadHolderTLS { private: EventPipeThreadHolder *m_threadHolder; - static thread_local EventPipeCoreCLRThreadHolderTLS g_threadHolderTLS; + static thread_local EventPipeAotThreadHolderTLS g_threadHolderTLS; }; static @@ -2856,8 +2857,10 @@ ep_rt_thread_setup (void) { STATIC_CONTRACT_NOTHROW; - Thread* thread_handle = SetupThreadNoThrow (); - EP_ASSERT (thread_handle != NULL); + // TODO: Implement thread creation/management if needed + // Thread* thread_handle = SetupThreadNoThrow (); + // EP_ASSERT (thread_handle != NULL); + //__debugbreak(); } static @@ -2867,7 +2870,7 @@ ep_rt_thread_get (void) { STATIC_CONTRACT_NOTHROW; - EventPipeThreadHolder *thread_holder = EventPipeCoreCLRThreadHolderTLS::getThreadHolder (); + EventPipeThreadHolder *thread_holder = EventPipeAotThreadHolderTLS::getThreadHolder (); return thread_holder ? ep_thread_holder_get_thread (thread_holder) : NULL; } @@ -2878,9 +2881,9 @@ ep_rt_thread_get_or_create (void) { STATIC_CONTRACT_NOTHROW; - EventPipeThreadHolder *thread_holder = EventPipeCoreCLRThreadHolderTLS::getThreadHolder (); + EventPipeThreadHolder *thread_holder = EventPipeAotThreadHolderTLS::getThreadHolder (); if (!thread_holder) - thread_holder = EventPipeCoreCLRThreadHolderTLS::createThreadHolder (); + thread_holder = EventPipeAotThreadHolderTLS::createThreadHolder (); return ep_thread_holder_get_thread (thread_holder); } @@ -2891,7 +2894,9 @@ ep_rt_thread_handle_t ep_rt_thread_get_handle (void) { STATIC_CONTRACT_NOTHROW; - return GetThreadNULLOk (); + // TODO: Implement thread creation/management if needed + // return GetThreadNULLOk (); + return NULL; } static @@ -2902,7 +2907,10 @@ ep_rt_thread_get_id (ep_rt_thread_handle_t thread_handle) STATIC_CONTRACT_NOTHROW; EP_ASSERT (thread_handle != NULL); - return ep_rt_uint64_t_to_thread_id_t (thread_handle->GetOSThreadId64 ()); + // TODO: Implement thread creation/management if needed + // return ep_rt_uint64_t_to_thread_id_t (thread_handle->GetOSThreadId64 ()); + __debugbreak(); + return NULL; } static @@ -2927,7 +2935,9 @@ bool ep_rt_thread_has_started (ep_rt_thread_handle_t thread_handle) { STATIC_CONTRACT_NOTHROW; - return thread_handle != NULL && thread_handle->HasStarted (); + // TODO: Implement thread creation/management if needed + // return thread_handle != NULL && thread_handle->HasStarted (); + return true; } static @@ -2936,7 +2946,10 @@ ep_rt_thread_activity_id_handle_t ep_rt_thread_get_activity_id_handle (void) { STATIC_CONTRACT_NOTHROW; - return GetThread (); + // TODO: Implement thread creation/management if needed + // return GetThread (); + __debugbreak(); + return NULL; } static @@ -2947,7 +2960,10 @@ ep_rt_thread_get_activity_id_cref (ep_rt_thread_activity_id_handle_t activity_id STATIC_CONTRACT_NOTHROW; EP_ASSERT (activity_id_handle != NULL); - return reinterpret_cast(activity_id_handle->GetActivityId ()); + // TODO: Implement thread creation/management if needed + // return reinterpret_cast(activity_id_handle->GetActivityId ()); + __debugbreak(); + return NULL; } static @@ -2979,11 +2995,13 @@ ep_rt_thread_set_activity_id ( EP_ASSERT (activity_id != NULL); EP_ASSERT (activity_id_len == EP_ACTIVITY_ID_SIZE); - activity_id_handle->SetActivityId (reinterpret_cast(activity_id)); + // TODO: Implement thread creation/management if needed + // activity_id_handle->SetActivityId (reinterpret_cast(activity_id)); + __debugbreak(); } #undef EP_YIELD_WHILE -#define EP_YIELD_WHILE(condition) YIELD_WHILE(condition) +#define EP_YIELD_WHILE(condition) {}//YIELD_WHILE(condition) /* * ThreadSequenceNumberMap. diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h index 4eed50094dc45..8e395237f91c1 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h @@ -1,11 +1,13 @@ -// Implementation of ep-rt-types.h targeting aot runtime. +// Implementation of ep-rt-types.h targeting AOT runtime. #ifndef __EVENTPIPE_RT_TYPES_AOT_H__ #define __EVENTPIPE_RT_TYPES_AOT_H__ #include #ifdef ENABLE_PERFTRACING -#include "slist.h" + +#include "gcenv.h" +#include "EmptyContainers.h" #ifdef DEBUG #define EP_CHECKED_BUILD @@ -29,22 +31,22 @@ template struct _rt_aot_list_internal_t { - typedef struct SListElem element_type_t; - typedef class SList list_type_t; + typedef struct SListElem_EP element_type_t; + typedef class SList_EP list_type_t; list_type_t *list; }; template struct _rt_aot_queue_internal_t { - typedef struct SListElem element_type_t; - typedef class SList queue_type_t; + typedef struct SListElem_EP element_type_t; + typedef class SList_EP queue_type_t; queue_type_t *queue; }; template struct _rt_aot_array_internal_t { typedef T element_type_t; - typedef class CQuickArrayList array_type_t; + typedef class CQuickArrayList_EP array_type_t; array_type_t *array; }; @@ -62,23 +64,23 @@ typedef struct _rt_aot_table_callbacks_t { template struct _rt_aot_table_default_internal_t { - typedef class SHash > > table_type_t; + typedef class SHash_EP > > table_type_t; rt_aot_table_callbacks_t callbacks; table_type_t *table; }; template struct _rt_aot_table_remove_internal_t { - typedef class SHash< MapSHashTraits > table_type_t; + typedef class SHash_EP< MapSHashTraits_EP > table_type_t; rt_aot_table_callbacks_t callbacks; table_type_t *table; }; -class EventPipeAotStackHashTraits : public NoRemoveSHashTraits< MapSHashTraits > +class EventPipeAotStackHashTraits : public NoRemoveSHashTraits_EP< MapSHashTraits_EP > { public: - typedef typename MapSHashTraits::element_t element_t; - typedef typename MapSHashTraits::count_t count_t; + typedef typename MapSHashTraits_EP::element_t element_t; + typedef typename MapSHashTraits_EP::count_t count_t; typedef StackHashKey * key_t; @@ -88,7 +90,7 @@ class EventPipeAotStackHashTraits : public NoRemoveSHashTraits< MapSHashTraits struct _rt_aot_table_custom_internal_t { - typedef class SHash table_type_t; + typedef class SHash_EP table_type_t; rt_aot_table_callbacks_t callbacks; table_type_t *table; }; @@ -306,17 +308,17 @@ typedef class Thread * ep_rt_thread_handle_t; typedef class Thread * ep_rt_thread_activity_id_handle_t; #undef ep_rt_thread_id_t -#ifndef TARGET_UNIX -typedef DWORD ep_rt_thread_id_t; -#else +// #ifndef TARGET_UNIX +// typedef DWORD ep_rt_thread_id_t; +// #else typedef size_t ep_rt_thread_id_t; -#endif +//#endif #undef ep_rt_thread_start_func -typedef DWORD (WINAPI *ep_rt_thread_start_func)(LPVOID lpThreadParameter); +typedef size_t (__stdcall *ep_rt_thread_start_func)(void *lpThreadParameter); #undef ep_rt_thread_start_func_return_t -typedef DWORD ep_rt_thread_start_func_return_t; +typedef size_t ep_rt_thread_start_func_return_t; #undef ep_rt_thread_params_t typedef struct _rt_aot_thread_params_t { From 418f8c3f9e86d07ce6487c36ce8c5ff1e0deab12 Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Mon, 9 Jan 2023 09:30:48 -0800 Subject: [PATCH 04/32] hooks to EP library from AOT --- .../Runtime/AotDisabledEventPipeInterface.cpp | 12 + .../Runtime/AotEnabledEventPipeInterface.cpp | 17 + .../nativeaot/Runtime/EventPipeInterface.h | 19 + .../Runtime/diagnosticserveradapter.h | 42 ++ .../nativeaot/Runtime/eventpipeadapter.h | 584 ++++++++++++++++++ .../nativeaot/Runtime/eventpipeadaptertypes.h | 15 + src/coreclr/nativeaot/Runtime/startup.cpp | 15 + 7 files changed, 704 insertions(+) create mode 100644 src/coreclr/nativeaot/Runtime/AotDisabledEventPipeInterface.cpp create mode 100644 src/coreclr/nativeaot/Runtime/AotEnabledEventPipeInterface.cpp create mode 100644 src/coreclr/nativeaot/Runtime/EventPipeInterface.h create mode 100644 src/coreclr/nativeaot/Runtime/diagnosticserveradapter.h create mode 100644 src/coreclr/nativeaot/Runtime/eventpipeadapter.h create mode 100644 src/coreclr/nativeaot/Runtime/eventpipeadaptertypes.h diff --git a/src/coreclr/nativeaot/Runtime/AotDisabledEventPipeInterface.cpp b/src/coreclr/nativeaot/Runtime/AotDisabledEventPipeInterface.cpp new file mode 100644 index 0000000000000..cb654d81e4c3b --- /dev/null +++ b/src/coreclr/nativeaot/Runtime/AotDisabledEventPipeInterface.cpp @@ -0,0 +1,12 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +void EventPipeAdapter_Initialize() {} + +bool DiagnosticServerAdapter_Initialize() { return false; } +void DiagnosticServerAdapter_PauseForDiagnosticsMonitor() {} + +void EventPipeAdapter_FinishInitialize() {} + +void EventPipeAdapter_Shutdown() {} +bool DiagnosticServerAdapter_Shutdown() { return false; } diff --git a/src/coreclr/nativeaot/Runtime/AotEnabledEventPipeInterface.cpp b/src/coreclr/nativeaot/Runtime/AotEnabledEventPipeInterface.cpp new file mode 100644 index 0000000000000..2441322199e9c --- /dev/null +++ b/src/coreclr/nativeaot/Runtime/AotEnabledEventPipeInterface.cpp @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "eventpipeadapter.h" +#include "diagnosticserveradapter.h" + + +void EventPipeAdapter_Initialize() { EventPipeAdapter::Initialize(); } + +bool DiagnosticServerAdapter_Initialize() { return DiagnosticServerAdapter::Initialize(); } +void DiagnosticServerAdapter_PauseForDiagnosticsMonitor() { DiagnosticServerAdapter::PauseForDiagnosticsMonitor();} + + +void EventPipeAdapter_FinishInitialize() { EventPipeAdapter::FinishInitialize(); } + +void EventPipeAdapter_Shutdown() { EventPipeAdapter::Shutdown(); } +bool DiagnosticServerAdapter_Shutdown() { return DiagnosticServerAdapter::Shutdown(); } diff --git a/src/coreclr/nativeaot/Runtime/EventPipeInterface.h b/src/coreclr/nativeaot/Runtime/EventPipeInterface.h new file mode 100644 index 0000000000000..8015bc8f4c0c1 --- /dev/null +++ b/src/coreclr/nativeaot/Runtime/EventPipeInterface.h @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +#ifndef __EVENTPIPE_INTERFACE_H__ +#define __EVENTPIPE_INTERFACE_H__ + +// Initialize EventPipe +void EventPipeAdapter_Initialize(); + +// Initialize DS +bool DiagnosticServerAdapter_Initialize(); +void DiagnosticServerAdapter_PauseForDiagnosticsMonitor(); + + +void EventPipeAdapter_FinishInitialize(); + +void EventPipeAdapter_Shutdown(); +bool DiagnosticServerAdapter_Shutdown(); + +#endif //__EVENTPIPE_INTERFACE_H__ \ No newline at end of file diff --git a/src/coreclr/nativeaot/Runtime/diagnosticserveradapter.h b/src/coreclr/nativeaot/Runtime/diagnosticserveradapter.h new file mode 100644 index 0000000000000..62cd5816d08fd --- /dev/null +++ b/src/coreclr/nativeaot/Runtime/diagnosticserveradapter.h @@ -0,0 +1,42 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#ifndef __DIAGNOSTIC_SERVER_ADAPTER_H__ +#define __DIAGNOSTIC_SERVER_ADAPTER_H__ + +#if defined(FEATURE_PERFTRACING) + +#include + +class DiagnosticServerAdapter final +{ +public: + static inline bool Initialize() + { + return ds_server_init(); + } + + static inline bool Shutdown() + { + return ds_server_shutdown(); + } + + NOINLINE static void PauseForDiagnosticsMonitor() + { + return ds_server_pause_for_diagnostics_monitor(); + } + + static void ResumeRuntimeStartup() + { + return ds_server_resume_runtime_startup(); + } + + static bool IsPausedInRuntimeStartup() + { + return ds_server_is_paused_in_startup(); + } +}; + +#endif // FEATURE_PERFTRACING + +#endif // __DIAGNOSTIC_SERVER_ADAPTER_H__ diff --git a/src/coreclr/nativeaot/Runtime/eventpipeadapter.h b/src/coreclr/nativeaot/Runtime/eventpipeadapter.h new file mode 100644 index 0000000000000..4f498bf664ae8 --- /dev/null +++ b/src/coreclr/nativeaot/Runtime/eventpipeadapter.h @@ -0,0 +1,584 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#ifndef __EVENTPIPE_ADAPTER_H__ +#define __EVENTPIPE_ADAPTER_H__ + +#if defined(FEATURE_PERFTRACING) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#if defined(NATIVEAOT_CORPROF_INCLUDE_IS_READY) + +class EventPipeProviderConfigurationAdapter final +{ +public: + EventPipeProviderConfigurationAdapter(const COR_PRF_EVENTPIPE_PROVIDER_CONFIG *providerConfigs, uint32_t providerConfigsLen) + { + STATIC_CONTRACT_NOTHROW; + + // This static_assert will fail because EventPipeProviderConfiguration uses char8_t strings rather than char16_t strings. + // This method takes the COR_PRF variant and converts to char8_t strings, so it should be fine. + // Leaving the assert commented out here for posterity. + // + // static_assert(offsetof(EventPipeProviderConfiguration, provider_name) == offsetof(COR_PRF_EVENTPIPE_PROVIDER_CONFIG, providerName) + // && offsetof(EventPipeProviderConfiguration, keywords) == offsetof(COR_PRF_EVENTPIPE_PROVIDER_CONFIG, keywords) + // && offsetof(EventPipeProviderConfiguration, logging_level) == offsetof(COR_PRF_EVENTPIPE_PROVIDER_CONFIG, loggingLevel) + // && offsetof(EventPipeProviderConfiguration, filter_data) == offsetof(COR_PRF_EVENTPIPE_PROVIDER_CONFIG, filterData) + // && sizeof(EventPipeProviderConfiguration) == sizeof(COR_PRF_EVENTPIPE_PROVIDER_CONFIG), + // "Layouts of EventPipeProviderConfiguration type and COR_PRF_EVENTPIPE_PROVIDER_CONFIG type do not match!"); + + m_providerConfigs = new (nothrow) EventPipeProviderConfiguration[providerConfigsLen]; + m_providerConfigsLen = providerConfigsLen; + if (m_providerConfigs) { + for (uint32_t i = 0; i < providerConfigsLen; ++i) { + ep_provider_config_init ( + &m_providerConfigs[i], + ep_rt_utf16_to_utf8_string (reinterpret_cast(providerConfigs[i].providerName), -1), + providerConfigs[i].keywords, + static_cast(providerConfigs[i].loggingLevel), + ep_rt_utf16_to_utf8_string (reinterpret_cast(providerConfigs[i].filterData), -1)); + } + } + } + + ~EventPipeProviderConfigurationAdapter() + { + STATIC_CONTRACT_NOTHROW; + if (m_providerConfigs) { + for (uint32_t i = 0; i < m_providerConfigsLen; ++i) { + ep_rt_utf8_string_free ((ep_char8_t *)ep_provider_config_get_provider_name (&m_providerConfigs[i])); + ep_rt_utf8_string_free ((ep_char8_t *)ep_provider_config_get_filter_data (&m_providerConfigs[i])); + } + delete [] m_providerConfigs; + } + } + + inline const EventPipeProviderConfiguration * GetProviderConfigs() const + { + STATIC_CONTRACT_NOTHROW; + return m_providerConfigs; + } + + inline uint32_t GetProviderConfigsLen() const + { + STATIC_CONTRACT_NOTHROW; + return m_providerConfigsLen; + } + +private: + EventPipeProviderConfiguration *m_providerConfigs; + uint32_t m_providerConfigsLen; +}; + +class EventPipeParameterDescAdapter final +{ +public: + EventPipeParameterDescAdapter(COR_PRF_EVENTPIPE_PARAM_DESC *params, uint32_t paramsLen) + { + STATIC_CONTRACT_NOTHROW; + +#ifdef EP_INLINE_GETTER_SETTER + static_assert(offsetof(EventPipeParameterDesc, type) == offsetof(COR_PRF_EVENTPIPE_PARAM_DESC, type) + && offsetof(EventPipeParameterDesc, element_type) == offsetof(COR_PRF_EVENTPIPE_PARAM_DESC, elementType) + && offsetof(EventPipeParameterDesc, name) == offsetof(COR_PRF_EVENTPIPE_PARAM_DESC, name) + && sizeof(EventPipeParameterDesc) == sizeof(COR_PRF_EVENTPIPE_PARAM_DESC), + "Layouts of EventPipeParameterDesc type and COR_PRF_EVENTPIPE_PARAM_DESC type do not match!"); +#endif + m_params = reinterpret_cast(params); + m_paramsLen = paramsLen; + } + + inline const EventPipeParameterDesc * GetParams() const + { + STATIC_CONTRACT_NOTHROW; + return m_params; + } + + inline uint32_t GetParamsLen() const + { + STATIC_CONTRACT_NOTHROW; + return m_paramsLen; + } + +private: + EventPipeParameterDesc *m_params; + uint32_t m_paramsLen; +}; + +class EventDataAdapter final +{ +public: + EventDataAdapter(COR_PRF_EVENT_DATA *data, uint32_t dataLen) + { + STATIC_CONTRACT_NOTHROW; + +#ifdef EP_INLINE_GETTER_SETTER + static_assert(offsetof(EventData, ptr) == offsetof(COR_PRF_EVENT_DATA, ptr) + && offsetof(EventData, size) == offsetof(COR_PRF_EVENT_DATA, size) + && sizeof(EventData) == sizeof(COR_PRF_EVENT_DATA), + "Layouts of EventData type and COR_PRF_EVENT_DATA type do not match!"); +#endif + m_data = reinterpret_cast(data); + m_dataLen = dataLen; + } + + inline const EventData * GetData() const + { + STATIC_CONTRACT_NOTHROW; + return m_data; + } + + inline uint32_t GetDataLen() const + { + STATIC_CONTRACT_NOTHROW; + return m_dataLen; + } + +private: + EventData *m_data; + uint32_t m_dataLen; +}; + +#endif // defined(NATIVEAOT_CORPROF_INCLUDE_IS_READY) + +class EventPipeAdapter final +{ +public: + static inline void Initialize() + { + CONTRACTL + { + NOTHROW; + } + CONTRACTL_END; + + ep_init(); + } + + static inline EventPipeProvider * CreateProvider(LPCWSTR providerName, EventPipeCallback callback, void* pCallbackContext) + { + ep_char8_t *providerNameUTF8 = ep_rt_utf16_to_utf8_string(reinterpret_cast(providerName), -1); + EventPipeProvider * provider = ep_create_provider (providerNameUTF8, callback, pCallbackContext); + ep_rt_utf8_string_free (providerNameUTF8); + return provider; + } + + static inline void DeleteProvider (EventPipeProvider * provider) + { + ep_delete_provider (provider); + } + + + static inline void FinishInitialize() + { + CONTRACTL + { + NOTHROW; + } + CONTRACTL_END; + + ep_finish_init(); + } + + static inline void Shutdown() + { + ep_shutdown(); + } + + static inline bool Enabled() + { + STATIC_CONTRACT_NOTHROW; + return ep_enabled(); + } + +#if defined(NATIVEAOT_CORPROF_INCLUDE_IS_READY) + static inline EventPipeSessionID Enable( + LPCWSTR outputPath, + uint32_t circularBufferSizeInMB, + const EventPipeProviderConfigurationAdapter &providerConfigs, + EventPipeSessionType sessionType, + EventPipeSerializationFormat format, + const bool rundownRequested, + IpcStream *const stream, + EventPipeSessionSynchronousCallback callback, + void *callbackAdditionalData) + { + CONTRACTL + { + NOTHROW; + GC_TRIGGERS; + MODE_PREEMPTIVE; + } + CONTRACTL_END; + + ep_char8_t *outputPathUTF8 = NULL; + if (outputPath) + outputPathUTF8 = ep_rt_utf16_to_utf8_string (reinterpret_cast(outputPath), -1); + EventPipeSessionID result = ep_enable ( + outputPathUTF8, + circularBufferSizeInMB, + providerConfigs.GetProviderConfigs(), + providerConfigs.GetProviderConfigsLen(), + sessionType, + format, + rundownRequested, + stream, + callback, + callbackAdditionalData); + ep_rt_utf8_string_free (outputPathUTF8); + return result; + } + + static inline void Disable(EventPipeSessionID id) + { + CONTRACTL + { + NOTHROW; + GC_TRIGGERS; + MODE_ANY; + } + CONTRACTL_END; + + ep_disable(id); + } + + static inline void StartStreaming(EventPipeSessionID id) + { + CONTRACTL + { + NOTHROW; + GC_TRIGGERS; + MODE_ANY; + } + CONTRACTL_END; + + ep_start_streaming(id); + } + + static inline EventPipeSession * GetSession(EventPipeSessionID id) + { + STATIC_CONTRACT_NOTHROW; + return ep_get_session(id); + } + + static inline bool SignalSession(EventPipeSessionID id) + { + STATIC_CONTRACT_NOTHROW; + + EventPipeSession *const session = ep_get_session (id); + if (!session) + return false; + + return ep_rt_wait_event_set (ep_session_get_wait_event (session)); + } + + static inline bool WaitForSessionSignal(EventPipeSessionID id, INT32 timeoutMs) + { + STATIC_CONTRACT_NOTHROW; + + EventPipeSession *const session = ep_get_session (id); + if (!session) + return false; + + return !ep_rt_wait_event_wait (ep_session_get_wait_event (session), (uint32_t)timeoutMs, false) ? true : false; + } + + static inline FILETIME GetSessionStartTime(EventPipeSession *session) + { + STATIC_CONTRACT_NOTHROW; + + FILETIME fileTime; + LARGE_INTEGER largeValue; + + _ASSERTE(session != NULL); + largeValue.QuadPart = ep_session_get_session_start_time(session); + fileTime.dwLowDateTime = largeValue.u.LowPart; + fileTime.dwHighDateTime = largeValue.u.HighPart; + return fileTime; + } + + static inline LONGLONG GetSessionStartTimestamp(EventPipeSession *session) + { + STATIC_CONTRACT_NOTHROW; + + _ASSERTE(session != NULL); + return ep_session_get_session_start_timestamp(session); + } + + static inline void AddProviderToSession(EventPipeSessionProvider *provider, EventPipeSession *session) + { + CONTRACTL + { + NOTHROW; + GC_TRIGGERS; + MODE_PREEMPTIVE; + } + CONTRACTL_END; + + ep_add_provider_to_session (provider, session); + } + + static inline EventPipeProvider * GetProvider (LPCWSTR providerName) + { + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + } + CONTRACTL_END; + + if (!providerName) + return NULL; + + ep_char8_t *providerNameUTF8 = ep_rt_utf16_to_utf8_string(reinterpret_cast(providerName), -1); + EventPipeProvider * provider = ep_get_provider (providerNameUTF8); + ep_rt_utf8_string_free(providerNameUTF8); + return provider; + } + + static EventPipeSessionProvider * CreateSessionProvider(const EventPipeProviderConfigurationAdapter &providerConfig) + { + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + } + CONTRACTL_END; + + _ASSERTE (providerConfig.GetProviderConfigs() != NULL && providerConfig.GetProviderConfigsLen() == 1); + const EventPipeProviderConfiguration *config = providerConfig.GetProviderConfigs(); + if (!config) + return NULL; + + return ep_session_provider_alloc ( + ep_provider_config_get_provider_name (&config[0]), + ep_provider_config_get_keywords (&config[0]), + (EventPipeEventLevel)ep_provider_config_get_logging_level (&config[0]), + ep_provider_config_get_filter_data (&config[0])); + } + + static HRESULT GetProviderName(const EventPipeProvider *provider, ULONG numNameChars, ULONG *numNameCharsOut, LPWSTR name) + { + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + } + CONTRACTL_END; + + _ASSERTE(provider != NULL); + + HRESULT hr = S_OK; + const ep_char16_t *providerName = ep_provider_get_provider_name_utf16 (provider); + if (providerName) { + uint32_t numProviderNameChars = (uint32_t)(ep_rt_utf16_string_len (providerName) + 1); + if (numNameCharsOut) + *numNameCharsOut = numProviderNameChars; + if (numProviderNameChars >= numNameChars) + hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); + else if (name) + memcpy (name, providerName, numProviderNameChars * sizeof (ep_char16_t)); + } + return hr; + } + + static EventPipeEvent * AddEvent( + EventPipeProvider *provider, + uint32_t eventID, + LPCWSTR eventName, + int64_t keywords, + uint32_t eventVersion, + EventPipeEventLevel level, + uint8_t opcode, + const EventPipeParameterDescAdapter ¶ms, + bool needStack) + { + + size_t metadataLen = 0; + EventPipeEvent *realEvent = NULL; + uint8_t *metadata = ep_metadata_generator_generate_event_metadata ( + eventID, + reinterpret_cast(eventName), + keywords, + eventVersion, + level, + opcode, + (EventPipeParameterDesc *)params.GetParams(), + params.GetParamsLen(), + &metadataLen); + if (metadata) { + realEvent = ep_provider_add_event( + provider, + eventID, + keywords, + eventVersion, + level, + needStack, + metadata, + (uint32_t)metadataLen); + ep_rt_byte_array_free(metadata); + } + return realEvent; + } + +#endif // defined(NATIVEAOT_CORPROF_INCLUDE_IS_READY) + + static inline EventPipeEvent * AddEvent( + EventPipeProvider *provider, + uint32_t eventID, + int64_t keywords, + uint32_t eventVersion, + EventPipeEventLevel level, + bool needStack, + uint8_t *metadata = NULL, + uint32_t metadataLen = 0) + { + return ep_provider_add_event(provider, eventID, keywords, eventVersion, level, needStack, metadata, metadataLen); + } + + static inline void WriteEvent( + EventPipeEvent *ep_event, + uint8_t *data, + uint32_t dataLen, + const GUID * activityId, + const GUID * relatedActivityId) + { + ep_write_event( + ep_event, + data, + dataLen, + reinterpret_cast(activityId), + reinterpret_cast(relatedActivityId)); + } + + static inline void WriteEvent( + EventPipeEvent *ep_event, + EventData *data, + uint32_t dataLen, + const GUID * activityId, + const GUID * relatedActivityId) + { + ep_write_event_2( + ep_event, + data, + dataLen, + reinterpret_cast(activityId), + reinterpret_cast(relatedActivityId)); + } + +#if defined(NATIVEAOT_CORPROF_INCLUDE_IS_READY) + static inline void WriteEvent( + EventPipeEvent *ep_event, + EventDataAdapter &data, + const GUID * activityId, + const GUID * relatedActivityId) + { + WriteEvent( + ep_event, + (EventData*)data.GetData(), + data.GetDataLen(), + activityId, + relatedActivityId); + } + + static inline bool EventIsEnabled (const EventPipeEvent *epEvent) + { + STATIC_CONTRACT_NOTHROW; + return ep_event_is_enabled(epEvent); + } + + static inline EventPipeEventInstance * GetNextEvent (EventPipeSessionID id) + { + CONTRACTL + { + NOTHROW; + GC_TRIGGERS; + MODE_PREEMPTIVE; + } + CONTRACTL_END; + + return ep_get_next_event(id); + } + + static inline EventPipeProvider * GetEventProvider (EventPipeEventInstance *eventInstance) + { + STATIC_CONTRACT_NOTHROW; + return ep_event_get_provider(ep_event_instance_get_ep_event(eventInstance)); + } + + static inline uint32_t GetEventID (EventPipeEventInstance *eventInstance) + { + STATIC_CONTRACT_NOTHROW; + return ep_event_get_event_id(ep_event_instance_get_ep_event(eventInstance)); + } + + static inline uint64_t GetEventThreadID (EventPipeEventInstance *eventInstance) + { + STATIC_CONTRACT_NOTHROW; + return ep_event_instance_get_thread_id(eventInstance); + } + + static inline int64_t GetEventTimestamp (EventPipeEventInstance *eventInstance) + { + STATIC_CONTRACT_NOTHROW; + return ep_event_instance_get_timestamp(eventInstance); + } + + static inline LPCGUID GetEventActivityID (EventPipeEventInstance *eventInstance) + { + STATIC_CONTRACT_NOTHROW; + static_assert(sizeof(GUID) == EP_ACTIVITY_ID_SIZE, "Size mismatch, sizeof(GUID) should be equal to EP_ACTIVITY_ID_SIZE"); + return reinterpret_cast(ep_event_instance_get_activity_id_cref(eventInstance)); + } + + static inline LPCGUID GetEventRelativeActivityID (EventPipeEventInstance *eventInstance) + { + STATIC_CONTRACT_NOTHROW; + static_assert(sizeof(GUID) == EP_ACTIVITY_ID_SIZE, "Size mismatch, sizeof(GUID) should be equal to EP_ACTIVITY_ID_SIZE"); + return reinterpret_cast(ep_event_instance_get_related_activity_id_cref(eventInstance)); + } + + static inline const uint8_t * GetEventData (EventPipeEventInstance *eventInstance) + { + STATIC_CONTRACT_NOTHROW; + return ep_event_instance_get_data(eventInstance); + } + + static inline uint32_t GetEventDataLen (EventPipeEventInstance *eventInstance) + { + STATIC_CONTRACT_NOTHROW; + return ep_event_instance_get_data_len(eventInstance); + } + + static inline void ResumeSession (EventPipeSession *session) + { + STATIC_CONTRACT_NOTHROW; + ep_session_resume (session); + } + + static inline void PauseSession (EventPipeSession *session) + { + STATIC_CONTRACT_NOTHROW; + ep_session_pause (session); + } + +#endif // defined(NATIVEAOT_CORPROF_INCLUDE_IS_READY) + +}; + +#endif // FEATURE_PERFTRACING +#endif // __EVENTPIPE_ADAPTER_H__ diff --git a/src/coreclr/nativeaot/Runtime/eventpipeadaptertypes.h b/src/coreclr/nativeaot/Runtime/eventpipeadaptertypes.h new file mode 100644 index 0000000000000..f473bde10488d --- /dev/null +++ b/src/coreclr/nativeaot/Runtime/eventpipeadaptertypes.h @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#ifndef __EVENTPIPE_ADAPTER_TYPES_H__ +#define __EVENTPIPE_ADAPTER_TYPES_H__ + +#if defined(FEATURE_PERFTRACING) + +typedef struct _EventFilterDescriptor EventFilterDescriptor; +typedef struct _EventPipeBufferList EventPipeBufferList; +typedef struct _EventPipeProvider EventPipeProvider; +typedef struct _EventPipeSession EventPipeSession; + +#endif // FEATURE_PERFTRACING +#endif // __EVENTPIPE_ADAPTER_TYPES_H__ diff --git a/src/coreclr/nativeaot/Runtime/startup.cpp b/src/coreclr/nativeaot/Runtime/startup.cpp index 1c599b2e2481b..697f008f734c2 100644 --- a/src/coreclr/nativeaot/Runtime/startup.cpp +++ b/src/coreclr/nativeaot/Runtime/startup.cpp @@ -26,6 +26,7 @@ #include "stressLog.h" #include "RestrictedCallouts.h" #include "yieldprocessornormalized.h" +#include "EventPipeInterface.h" #ifndef DACCESS_COMPILE @@ -98,6 +99,12 @@ static bool InitDLL(HANDLE hPalInstance) return false; #endif + // Initialize EventPipe + EventPipeAdapter_Initialize(); + // Initialize DS + DiagnosticServerAdapter_Initialize(); + DiagnosticServerAdapter_PauseForDiagnosticsMonitor(); + // // Initialize support for registering GC and HandleTable callouts. // @@ -142,6 +149,11 @@ static bool InitDLL(HANDLE hPalInstance) STARTUP_TIMELINE_EVENT(GC_INIT_COMPLETE); + // Finish setting up rest of EventPipe - specifically enable SampleProfiler if it was requested at startup. + // SampleProfiler needs to cooperate with the GC which hasn't fully finished setting up in the first part of the + // EventPipe initialization, so this is done after the GC has been fully initialized. + EventPipeAdapter_FinishInitialize(); + #ifndef USE_PORTABLE_HELPERS if (!DetectCPUFeatures()) return false; @@ -460,6 +472,9 @@ static void __cdecl OnProcessExit() // or run managed code at shutdown, so we will not try detaching it. Thread* currentThread = ThreadStore::RawGetCurrentThread(); g_threadPerformingShutdown = currentThread; + + EventPipeAdapter_Shutdown(); + DiagnosticServerAdapter_Shutdown(); } #endif From 179585eadb355250ef2f7bbe8aea9e77b19a30ac Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Mon, 9 Jan 2023 09:51:51 -0800 Subject: [PATCH 05/32] Container code --- .../nativeaot/Runtime/EmptyContainers.h | 320 ++++++++++ .../nativeaot/Runtime/EmptyContainers2.h | 557 ++++++++++++++++++ 2 files changed, 877 insertions(+) create mode 100644 src/coreclr/nativeaot/Runtime/EmptyContainers.h create mode 100644 src/coreclr/nativeaot/Runtime/EmptyContainers2.h diff --git a/src/coreclr/nativeaot/Runtime/EmptyContainers.h b/src/coreclr/nativeaot/Runtime/EmptyContainers.h new file mode 100644 index 0000000000000..9a044389fb00c --- /dev/null +++ b/src/coreclr/nativeaot/Runtime/EmptyContainers.h @@ -0,0 +1,320 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#ifndef __EmptyContainers_h__ +#define __EmptyContainers_h__ + +// This header file will contains minimal containers that are needed for EventPipe library implementation +// @TODO - this will likely be replaced by the common container classes to be added to the EventPipe library +// Hence initially, the bare boned implementation focus is on unblocking HW/Simple Trace bring up + +#include "EmptyContainers2.h" + +struct SLink_EP +{ + SLink_EP* m_pNext; + + SLink_EP() + { + m_pNext = NULL; + } + + // find pLink within the list starting at pHead + // if found remove the link from the list and return the link + // otherwise return NULL + static SLink_EP* FindAndRemove(SLink_EP *pHead, SLink_EP* pLink, SLink_EP ** ppPrior) + { + + _ASSERTE(pHead != NULL); + _ASSERTE(pLink != NULL); + + SLink_EP* pFreeLink = NULL; + *ppPrior = NULL; + + while (pHead->m_pNext != NULL) + { + if (pHead->m_pNext == pLink) + { + pFreeLink = pLink; + pHead->m_pNext = pLink->m_pNext; + *ppPrior = pHead; + break; + } + pHead = pHead->m_pNext; + } + + return pFreeLink; + } +}; + + +// template +// Assumes fHead to be false +template +class SList_EP +{ +protected: + // used as sentinel + SLink_EP m_link; + SLink_EP* m_pHead; + SLink_EP* m_pTail; + + // get the list node within the object + static SLink_EP* GetLink (T* pLink) + { + return &(pLink->m_Link); + } + + static T* GetObject (SLink_EP* pLink) + { + if (pLink == NULL) + return NULL; + return reinterpret_cast(reinterpret_cast(pLink) - offsetof(T, m_Link)); + } + +public: + + SList_EP() + { + m_pHead = &m_link; + // NOTE :: fHead variable is template argument + // the following code is a compiled in, only if the fHead flag + // is set to false, + m_pTail = &m_link; + // TODO: Likely not needed now since SLink_EP has a ctor + m_link.m_pNext = NULL; + } + + bool IsEmpty() + { + return m_pHead->m_pNext == NULL; + } + + void InsertTail(T *pObj) + { + _ASSERTE(pObj != NULL); + SLink_EP *pLink = GetLink(pObj); + + m_pTail->m_pNext = pLink; + m_pTail = pLink; + } + + T* RemoveHead() + { + SLink_EP* pLink = m_pHead->m_pNext; + if (pLink != NULL) + { + m_pHead->m_pNext = pLink->m_pNext; + } + + if(m_pTail == pLink) + { + m_pTail = m_pHead; + } + + return GetObject(pLink); + } + + T* GetHead() + { + return GetObject(m_pHead->m_pNext); + } + + static T *GetNext(T *pObj) + { + _ASSERTE(pObj != NULL); + return GetObject(GetLink(pObj)->m_pNext); + } + + + T* FindAndRemove(T *pObj) + { + _ASSERTE(pObj != NULL); + + SLink_EP *prior; + SLink_EP *ret = SLink_EP::FindAndRemove(m_pHead, GetLink(pObj), &prior); + + if (ret == m_pTail) + m_pTail = prior; + + return GetObject(ret); + } + + void InsertHead(T *pObj) + { + __debugbreak(); + } + + + class Iterator + { + friend class SList_EP; + //T* _t; + + public: + Iterator & operator++() + { + _ASSERTE(m_cur != NULL); + m_cur = SList_EP::GetNext(m_cur); + return *this; + } + + Iterator operator++(int) + { + Iterator it(m_cur); + ++(*this); + return it; + } + + bool operator==(Iterator const & other) const + { + return m_cur == other.m_cur || + (m_cur != NULL && other.m_cur != NULL && *m_cur == *other.m_cur); + } + + T & operator*() + { + _ASSERTE(m_cur != NULL); + return *m_cur; + } + + T * operator->() const + { + __debugbreak(); + return m_cur; + } + + private: + // Iterator(SList * pList) + // : m_cur(pList->GetHead()) + // { } + + Iterator(T* pObj) + : m_cur(pObj) + { } + + Iterator() + : m_cur(NULL) + { } + + T* m_cur; + + }; + + Iterator begin() + { + return Iterator(GetHead()); + } + + Iterator end() + { + return Iterator(); + } + +}; + +template +struct SListElem_EP +{ + SLink_EP m_Link; + ElemT m_Value; + + operator ElemT const &() const + { + return m_Value; + } + + operator ElemT &() + { + return m_Value; + } + + ElemT const & operator*() const + { + __debugbreak(); + return m_Value; + } + + ElemT & operator*() + { + __debugbreak(); + return m_Value; + } + + SListElem_EP() + : m_Link() + , m_Value() + { + } + + template + SListElem_EP(T1&& val) + : m_Link() + , m_Value(std::forward(val)) + { + } + + ElemT & GetValue() + { + return m_Value; + } + +}; + +// Bare boned implementation to unblock HW +template +class CQuickArrayList_EP +{ +private: + size_t m_curSize; + T *m_array; + size_t maxSize; +public: + CQuickArrayList_EP() + : m_curSize(0), maxSize(100) + { + m_array = new T[maxSize]; + } + + + T* AllocNoThrow(size_t iItems) + { + return new T[iItems]; + } + + bool PushNoThrow(const T & value) + { + if(m_curSize >= maxSize) + __debugbreak(); + m_array[m_curSize++] = value; + return true; + } + + size_t Size() const + { + return m_curSize; + } + + T Pop() + { + T t = m_array[m_curSize]; + m_curSize--; + return t; + } + + void Shrink() + { + } + + T& operator[] (size_t ix) + { + return m_array[ix]; + } + + T* Ptr() + { + return m_array; + } +}; + +#endif // __EmptyContainers_h__ diff --git a/src/coreclr/nativeaot/Runtime/EmptyContainers2.h b/src/coreclr/nativeaot/Runtime/EmptyContainers2.h new file mode 100644 index 0000000000000..eed1fb6916c52 --- /dev/null +++ b/src/coreclr/nativeaot/Runtime/EmptyContainers2.h @@ -0,0 +1,557 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#ifndef __EmptyContainers2_h__ +#define __EmptyContainers2_h__ + +// This header file will contains minimal containers that are needed for EventPipe library implementation +// @TODO - this will likely be replaced by the common container classes to be added to the EventPipe library +// Hence initially, the bare boned implementation focus is on unblocking HW/Simple Trace bring up + +// TODO: Should shash.h FailureType be used instead? +enum FailureType_EP { ftAllocation_EP, ftOverflow_EP }; + +template < typename ELEMENT, typename COUNT_T = uint32_t > +class DefaultSHashTraits_EP +{ +public: + typedef COUNT_T count_t; + typedef ELEMENT element_t; + typedef DPTR(element_t) PTR_element_t; // by default SHash is DAC-aware. For RS + // only SHash use NonDacAwareSHashTraits + // (which typedefs element_t* PTR_element_t) + + static const count_t s_growth_factor_numerator = 3; + static const count_t s_growth_factor_denominator = 2; + + static const count_t s_density_factor_numerator = 3; + static const count_t s_density_factor_denominator = 4; + + static const count_t s_minimum_allocation = 7; + + static const bool s_NoThrow = true; + + static const ELEMENT Null() { return (const ELEMENT) 0; } + static const ELEMENT Deleted() { return (const ELEMENT) -1; } + static bool IsNull(const ELEMENT &e) { return e == (const ELEMENT) 0; } + static bool IsDeleted(const ELEMENT &e) + { + __debugbreak(); + return false; + //return e == (const ELEMENT) -1; + } + + static void OnFailure(FailureType_EP /*ft*/) { } + +}; + +template +class SHash_EP : public TRAITS +{ + public: + class Index; + friend class Index; + class Iterator; + + typedef typename TRAITS::element_t element_t; + typedef typename TRAITS::PTR_element_t PTR_element_t; + typedef typename TRAITS::key_t key_t; + typedef typename TRAITS::count_t count_t; + + SHash_EP():m_table(nullptr), + m_tableSize(0), + m_tableCount(0), + m_tableOccupied(0), + m_tableMax(0) + { + } + + ~SHash_EP() + { + delete [] m_table; + } + + const element_t * Lookup(element_t* table, count_t tableSize, key_t key) const + { + if (tableSize == 0) + return NULL; + + count_t hash = TRAITS::Hash(key); + count_t index = hash % tableSize; + count_t increment = 0; // delay computation + + while (true) + { + element_t& current = table[index]; + + if (TRAITS::IsNull(current)) + return NULL; + + if (!TRAITS::IsDeleted(current) + && TRAITS::Equals(key, TRAITS::GetKey(current))) + { + return ¤t; + } + + if (increment == 0) + increment = (hash % (tableSize-1)) + 1; + + index += increment; + if (index >= tableSize) + index -= tableSize; + } + + } + + const element_t* LookupPtr(key_t key) const + { + return Lookup(m_table, m_tableSize, key); + } + + bool Add(const element_t &element) + { + if (!CheckGrowth()) + return false; + + if (Add(m_table, m_tableSize, element)) + m_tableOccupied++; + m_tableCount++; + + return true; + } + + bool CheckGrowth() + { + if (m_tableOccupied == m_tableMax) + { + return Grow(); + } + + return true; + } + + bool Reallocate(count_t newTableSize) + { + ASSERT(newTableSize >= + (count_t) (GetCount() * TRAITS::s_density_factor_denominator / TRAITS::s_density_factor_numerator)); + + // Allocation size must be a prime number. This is necessary so that hashes uniformly + // distribute to all indices, and so that chaining will visit all indices in the hash table. + newTableSize = NextPrime(newTableSize); + if (newTableSize == 0) + { + TRAITS::OnFailure(ftOverflow_EP); + return false; + } + + element_t *newTable = new (nothrow) element_t [newTableSize]; + if (newTable == NULL) + { + TRAITS::OnFailure(ftAllocation_EP); + return false; + } + + element_t *p = newTable, *pEnd = newTable + newTableSize; + while (p < pEnd) + { + *p = TRAITS::Null(); + p++; + } + + for (Iterator i = Begin(), end = End(); i != end; i++) + { + const element_t & cur = (*i); + if (!TRAITS::IsNull(cur) && !TRAITS::IsDeleted(cur)) + Add(newTable, newTableSize, cur); + } + + // @todo: + // We might want to try to delay this cleanup to allow asynchronous readers + + delete [] m_table; + + m_table = PTR_element_t(newTable); + m_tableSize = newTableSize; + m_tableMax = (count_t) (newTableSize * TRAITS::s_density_factor_numerator / TRAITS::s_density_factor_denominator); + m_tableOccupied = m_tableCount; + + return true; + } + + // + // Enumerator, provides a template to produce an iterator on an existing class + // with a single iteration variable. + // + + template + class Enumerator + { + private: + const SUBTYPE *This() const + { + return (const SUBTYPE *) this; + } + + SUBTYPE *This() + { + return (SUBTYPE *)this; + } + + public: + + Enumerator() + { + } + + const element_t &operator*() const + { + return This()->Get(); + } + const element_t *operator->() const + { + return &(This()->Get()); + } + SUBTYPE &operator++() + { + This()->Next(); + return *This(); + } + SUBTYPE operator++(int) + { + SUBTYPE i = *This(); + This()->Next(); + return i; + } + bool operator==(const SUBTYPE &i) const + { + return This()->Equal(i); + } + bool operator!=(const SUBTYPE &i) const + { + return !This()->Equal(i); + } + }; + + // + // Index for whole table iterator. This is also the base for the keyed iterator. + // + + class Index + { + friend class SHash_EP; + friend class Iterator; + friend class Enumerator; + + // The methods implementation has to be here for portability + // Some compilers won't compile the separate implementation in shash.inl + protected: + + PTR_element_t m_table; + count_t m_tableSize; + count_t m_index; + + Index(const SHash_EP *hash, bool begin) + : m_table(hash->m_table), + m_tableSize(hash->m_tableSize), + m_index(begin ? 0 : m_tableSize) + { + } + + const element_t &Get() const + { + return m_table[m_index]; + } + + void First() + { + if (m_index < m_tableSize) + if (TRAITS::IsNull(m_table[m_index]) || TRAITS::IsDeleted(m_table[m_index])) + Next(); + } + + void Next() + { + if (m_index >= m_tableSize) + return; + + for (;;) + { + m_index++; + if (m_index >= m_tableSize) + break; + if (!TRAITS::IsNull(m_table[m_index]) && !TRAITS::IsDeleted(m_table[m_index])) + break; + } + } + + bool Equal(const Index &i) const + { + return i.m_index == m_index; + } + }; + + + class Iterator : public Index, public Enumerator + { + friend class SHash_EP; + TRAITS* _t; + + public: + Iterator(const SHash_EP *hash, bool begin) + : Index(hash, begin) + { + } + }; + + Iterator Begin() const + { + Iterator i(this, true); + i.First(); + return i; + } + Iterator End() const + { + return Iterator(this, false); + } + + bool AddNoThrow(const element_t &element) + { + __debugbreak(); + return false; + } + bool AddOrReplaceNoThrow(const element_t &element) + { + __debugbreak(); + return false; + } + + count_t GetCount() const + { + return m_tableCount; + } + + void Remove(key_t key) + { + __debugbreak(); + } + + // Remove the specific element. + void Remove(Iterator& i) + { + __debugbreak(); + } + void RemoveAll() + { + delete [] m_table; + + m_table = NULL; + m_tableSize = 0; + m_tableCount = 0; + m_tableOccupied = 0; + m_tableMax = 0; + } + + // Instance members + private: + PTR_element_t m_table; // pointer to table + count_t m_tableSize; // allocated size of table + count_t m_tableCount; // number of elements in table + count_t m_tableOccupied; // number, includes deleted slots + count_t m_tableMax; // maximum occupied count before reallocating + + bool Grow() + { + count_t newSize = (count_t) (m_tableCount + * TRAITS::s_growth_factor_numerator / TRAITS::s_growth_factor_denominator + * TRAITS::s_density_factor_denominator / TRAITS::s_density_factor_numerator); + if (newSize < TRAITS::s_minimum_allocation) + newSize = TRAITS::s_minimum_allocation; + + // handle potential overflow + if (newSize < m_tableCount) + { + TRAITS::OnFailure(ftOverflow_EP); + return false; + } + + return Reallocate(newSize); + } + + static bool IsPrime(count_t number) + { + // This is a very low-tech check for primality, which doesn't scale very well. + // There are more efficient tests if this proves to be burdensome for larger + // tables. + + if ((number&1) == 0) + return false; + + count_t factor = 3; + while (factor * factor <= number) + { + if ((number % factor) == 0) + return false; + factor += 2; + } + + return true; + } + + static constexpr uint32_t g_shash_primes[] = { + 11,17,23,29,37,47,59,71,89,107,131,163,197,239,293,353,431,521,631,761,919, + 1103,1327,1597,1931,2333,2801,3371,4049,4861,5839,7013,8419,10103,12143,14591, + 17519,21023,25229,30293,36353,43627,52361,62851,75431,90523, 108631, 130363, + 156437, 187751, 225307, 270371, 324449, 389357, 467237, 560689, 672827, 807403, + 968897, 1162687, 1395263, 1674319, 2009191, 2411033, 2893249, 3471899, 4166287, + 4999559, 5999471, 7199369 }; + + // Returns a prime larger than 'number' or 0, in case of overflow + static count_t NextPrime(count_t number) + { + for (int i = 0; i < (int) (sizeof(g_shash_primes) / sizeof(g_shash_primes[0])); i++) + { + if (g_shash_primes[i] >= number) + return (typename SHash_EP::count_t)(g_shash_primes[i]); + } + + if ((number&1) == 0) + number++; + + while (number != 1) + { + if (IsPrime(number)) + return number; + number += 2; + } + + return 0; + } + + static bool Add(element_t *table, count_t tableSize, const element_t &element) + { + key_t key = TRAITS::GetKey(element); + + count_t hash = TRAITS::Hash(key); + count_t index = hash % tableSize; + count_t increment = 0; // delay computation + + while (true) + { + element_t& current = table[index]; + + if (TRAITS::IsNull(current)) + { + table[index] = element; + return true; + } + + if (TRAITS::IsDeleted(current)) + { + table[index] = element; + return false; + } + + if (increment == 0) + increment = (hash % (tableSize-1)) + 1; + + index += increment; + if (index >= tableSize) + index -= tableSize; + } + } + +}; + +template +class KeyValuePair_EP{ + KEY key; + VALUE value; + +public: + KeyValuePair_EP() + { + } + + KeyValuePair_EP(const KEY& k, const VALUE& v) + : key(k), value(v) + { + } + + KEY const & Key() const + { + return key; + } + + VALUE const & Value() const + { + return value; + } +}; + +template +class NoRemoveSHashTraits_EP : public PARENT +{ +public: + typedef typename PARENT::element_t element_t; + typedef typename PARENT::count_t count_t; +}; + +template +class MapSHashTraits_EP : public DefaultSHashTraits_EP< KeyValuePair_EP > +{ +public: + typedef typename DefaultSHashTraits_EP< KeyValuePair_EP >::element_t element_t; + typedef typename DefaultSHashTraits_EP< KeyValuePair_EP >::count_t count_t; + + typedef KEY key_t; + typedef VALUE value_t; + + static key_t GetKey(element_t e) + { + //__debugbreak(); + return e.Key(); + } + static bool Equals(key_t k1, key_t k2) + { + //__debugbreak(); + return k1 == k2; + } + static count_t Hash(key_t k) + { + //__debugbreak(); + return (count_t)(size_t)k; + } + + static const element_t Null() + { + return element_t(KEY(),VALUE()); + } + // static const element_t Deleted() + // { + // __debugbreak(); + // return element_t(KEY(-1), VALUE()); + // } + static bool IsNull(const element_t &e) + { + return e.Key() == KEY(); + } + static bool IsDeleted(const element_t &e) + { + return e.Key() == KEY(-1); + } + + key_t const & Key() const + { + __debugbreak(); + return *(new KEY()); + } + + value_t const & Value() const + { + __debugbreak(); + return *(new VALUE()); + } +}; + + +#endif // __EmptyContainers2_h__ From 8502406eae38f0b40587d87f70258d13ffbe3a5b Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Mon, 9 Jan 2023 10:08:10 -0800 Subject: [PATCH 06/32] Maanged to Native hooks --- .../nativeaot/Runtime/eventpipeinternal.cpp | 129 ++++++++++++++ .../src/System.Private.CoreLib.csproj | 1 + .../Eventing/EventPipe.NativeAot.cs | 162 ++++++++++++++++++ .../src/System/Runtime/RuntimeImports.cs | 72 ++++++++ .../Diagnostics/Tracing/RuntimeEventSource.cs | 8 + .../src/System/Threading/Overlapped.cs | 2 + 6 files changed, 374 insertions(+) create mode 100644 src/coreclr/nativeaot/Runtime/eventpipeinternal.cpp create mode 100644 src/coreclr/nativeaot/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipe.NativeAot.cs diff --git a/src/coreclr/nativeaot/Runtime/eventpipeinternal.cpp b/src/coreclr/nativeaot/Runtime/eventpipeinternal.cpp new file mode 100644 index 0000000000000..038fb1af281d4 --- /dev/null +++ b/src/coreclr/nativeaot/Runtime/eventpipeinternal.cpp @@ -0,0 +1,129 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "common.h" +#include "eventpipeadapter.h" + +#ifdef FEATURE_PERFTRACING + +struct EventPipeEventInstanceData +{ + void *ProviderID; + unsigned int EventID; + unsigned int ThreadID; + LARGE_INTEGER TimeStamp; + GUID ActivityId; + GUID RelatedActivityId; + const uint8_t *Payload; + unsigned int PayloadLength; +}; + +struct EventPipeSessionInfo +{ + FILETIME StartTimeAsUTCFileTime; + LARGE_INTEGER StartTimeStamp; + LARGE_INTEGER TimeStampFrequency; +}; + +EXTERN_C NATIVEAOT_API uint64_t __cdecl RhEventPipeInternal_Enable( + LPCWSTR outputFile, + EventPipeSerializationFormat format, + uint32_t circularBufferSizeInMB, + /* COR_PRF_EVENTPIPE_PROVIDER_CONFIG */ const void * pProviders, + uint32_t numProviders) +{ + __debugbreak(); + return 0; +} + +EXTERN_C NATIVEAOT_API void __cdecl RhEventPipeInternal_Disable(uint64_t sessionID) +{ + __debugbreak(); +} + +EXTERN_C NATIVEAOT_API intptr_t __cdecl RhEventPipeInternal_CreateProvider( + LPCWSTR providerName, + EventPipeCallback pCallbackFunc, + void* pCallbackContext) +{ + EventPipeProvider* pProvider = EventPipeAdapter::CreateProvider(providerName, pCallbackFunc, pCallbackContext); + return reinterpret_cast(pProvider); +} + +EXTERN_C NATIVEAOT_API intptr_t __cdecl RhEventPipeInternal_DefineEvent( + intptr_t provHandle, + uint32_t eventID, + int64_t keywords, + uint32_t eventVersion, + uint32_t level, + void *pMetadata, + uint32_t metadataLength) +{ + EventPipeEvent *pEvent = NULL; + + _ASSERTE(provHandle != 0); + EventPipeProvider *pProvider = reinterpret_cast(provHandle); + pEvent = EventPipeAdapter::AddEvent(pProvider, eventID, keywords, eventVersion, (EventPipeEventLevel)level, /* needStack = */ true, (uint8_t *)pMetadata, metadataLength); + _ASSERTE(pEvent != NULL); + + return reinterpret_cast(pEvent); +} + +EXTERN_C NATIVEAOT_API intptr_t __cdecl RhEventPipeInternal_GetProvider(LPCWSTR providerName) +{ + __debugbreak(); + return 0; +} + +EXTERN_C NATIVEAOT_API void __cdecl RhEventPipeInternal_DeleteProvider(intptr_t provHandle) +{ + if (provHandle != 0) + { + EventPipeProvider *pProvider = reinterpret_cast(provHandle); + EventPipeAdapter::DeleteProvider(pProvider); + } +} + +EXTERN_C NATIVEAOT_API int __cdecl RhEventPipeInternal_EventActivityIdControl(uint32_t controlCode, GUID *pActivityId) +{ + __debugbreak(); + return 0; +} + +EXTERN_C NATIVEAOT_API void __cdecl RhEventPipeInternal_WriteEventData( + intptr_t eventHandle, + EventData *pEventData, + uint32_t eventDataCount, + const GUID * pActivityId, + const GUID * pRelatedActivityId) +{ + _ASSERTE(eventHandle != 0); + EventPipeEvent *pEvent = reinterpret_cast(eventHandle); + EventPipeAdapter::WriteEvent(pEvent, pEventData, eventDataCount, pActivityId, pRelatedActivityId); +} + +EXTERN_C NATIVEAOT_API UInt32_BOOL __cdecl RhEventPipeInternal_GetSessionInfo(uint64_t sessionID, EventPipeSessionInfo *pSessionInfo) +{ + __debugbreak(); + return FALSE; +} + +EXTERN_C NATIVEAOT_API UInt32_BOOL __cdecl RhEventPipeInternal_GetNextEvent(uint64_t sessionID, EventPipeEventInstanceData *pInstance) +{ + __debugbreak(); + return FALSE; +} + +EXTERN_C NATIVEAOT_API UInt32_BOOL __cdecl RhEventPipeInternal_SignalSession(uint64_t sessionID) +{ + __debugbreak(); + return FALSE; +} + +EXTERN_C NATIVEAOT_API UInt32_BOOL __cdecl RhEventPipeInternal_WaitForSessionSignal(uint64_t sessionID, int32_t timeoutMs) +{ + __debugbreak(); + return FALSE; +} + +#endif // FEATURE_PERFTRACING diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj index a71d455521e03..16899bbfd96cb 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj @@ -182,6 +182,7 @@ + diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipe.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipe.NativeAot.cs new file mode 100644 index 0000000000000..1a29085096d67 --- /dev/null +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipe.NativeAot.cs @@ -0,0 +1,162 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System.Runtime; +using System.Runtime.InteropServices; + +#if FEATURE_PERFTRACING + +namespace System.Diagnostics.Tracing +{ + // + // NOTE: + // + // The implementation below takes some manual marshaling actions to ensure arguments are in + // primitive form before they are passed through to the underlying RuntimeImports.Rh* + // function. + // + // These extra steps are necessary only if the RuntimeImports mechanism represents "raw" + // calls into the native runtime (as has been the case at least in the distant past). + // + // If the RuntimeImports mechanism automatically applies rich p/invoke marshaling to all of + // these calls, then all of the manual steps below are unnecessary and can be removed (by + // making the RuntimeImports.Rh* function signatures generally match the corresponding + // EventPipeInternal function signatures; in other words, by making the RuntimeImports.Rh* + // functions look like the QCalls in EventPipe.CoreCLR.cs). + // + internal static partial class EventPipeInternal + { + // + // These PInvokes are used by the configuration APIs to interact with EventPipe. + // + private static unsafe ulong Enable( + char* outputFile, + EventPipeSerializationFormat format, + uint circularBufferSizeInMB, + EventPipeProviderConfigurationNative* providers, + uint numProviders) + { + return RuntimeImports.RhEventPipeInternal_Enable( + outputFile, + (int)format, + circularBufferSizeInMB, + providers, + numProviders); + } + + internal static void Disable(ulong sessionID) + { + RuntimeImports.RhEventPipeInternal_Disable(sessionID); + } + + // + // These PInvokes are used by EventSource to interact with the EventPipe. + // + +// private static extern unsafe IntPtr CreateProvider(string providerName, IntPtr callbackFunc, IntPtr callbackContext); + + internal static unsafe IntPtr CreateProvider(string providerName, + delegate* unmanaged callbackFunc, + void* callbackContext) + => CreateProvider(providerName, (IntPtr)callbackFunc, (IntPtr)callbackContext); + //internal static unsafe IntPtr CreateProvider(string providerName, IntPtr callbackFunc, IntPtr callbackContext); + + internal static unsafe IntPtr CreateProvider(string providerName, IntPtr callbackFunc, IntPtr callbackContext) + { + fixed (char* pProviderName = providerName) + { + return RuntimeImports.RhEventPipeInternal_CreateProvider( + pProviderName, + callbackFunc, + callbackContext); + } + } + + internal static unsafe IntPtr DefineEvent( + IntPtr provHandle, + uint eventID, + long keywords, + uint eventVersion, + uint level, + void *pMetadata, + uint metadataLength) + { + return RuntimeImports.RhEventPipeInternal_DefineEvent( + provHandle, + eventID, + keywords, + eventVersion, + level, + pMetadata, + metadataLength); + } + + internal static unsafe IntPtr GetProvider(string providerName) + { + fixed (char* pProviderName = providerName) + { + return RuntimeImports.RhEventPipeInternal_GetProvider(pProviderName); + } + } + + internal static void DeleteProvider(IntPtr provHandle) + { + RuntimeImports.RhEventPipeInternal_DeleteProvider(provHandle); + } + + internal static unsafe int EventActivityIdControl(uint controlCode, ref Guid activityId) + { + // + // Ensure that the address passed to native code is never on the managed heap, while still + // managing the supplied byref in an in/out manner. + // + Guid localActivityId = activityId; + try { return RuntimeImports.RhEventPipeInternal_EventActivityIdControl(controlCode, &localActivityId); } + finally { activityId = localActivityId; } + } + + internal static unsafe void WriteEventData( + IntPtr eventHandle, + EventProvider.EventData* pEventData, + uint dataCount, + Guid* activityId, + Guid* relatedActivityId) + { + RuntimeImports.RhEventPipeInternal_WriteEventData( + eventHandle, + pEventData, + dataCount, + activityId, + relatedActivityId); + } + + // + // These PInvokes are used as part of the EventPipeEventDispatcher. + // + internal static unsafe bool GetSessionInfo(ulong sessionID, EventPipeSessionInfo* pSessionInfo) + { + uint rawBool = RuntimeImports.RhEventPipeInternal_GetSessionInfo(sessionID, pSessionInfo); + return (rawBool != 0); + } + + internal static unsafe bool GetNextEvent(ulong sessionID, EventPipeEventInstanceData* pInstance) + { + uint rawBool = RuntimeImports.RhEventPipeInternal_GetNextEvent(sessionID, pInstance); + return (rawBool != 0); + } + + internal static bool SignalSession(ulong sessionID) + { + uint rawBool = RuntimeImports.RhEventPipeInternal_SignalSession(sessionID); + return (rawBool != 0); + } + + internal static bool WaitForSessionSignal(ulong sessionID, int timeoutMs) + { + uint rawBool = RuntimeImports.RhEventPipeInternal_WaitForSessionSignal(sessionID, timeoutMs); + return (rawBool != 0); + } + } +} + +#endif // FEATURE_PERFTRACING + diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs index 91894b1559e4b..bb203368d6dbb 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs @@ -691,6 +691,78 @@ public GCFrameRegistration(void* allocation, uint elemCount, bool areByRefs = tr [RuntimeImport(RuntimeLibrary, "RhpEtwExceptionThrown")] internal static extern unsafe void RhpEtwExceptionThrown(char* exceptionTypeName, char* exceptionMessage, IntPtr faultingIP, long hresult); +#if FEATURE_PERFTRACING + + // + // EventPipeInternal helpers. + // + [LibraryImport(RuntimeLibrary)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static unsafe partial ulong RhEventPipeInternal_Enable( + char* outputFile, + int format, + uint circularBufferSizeInMB, + void* providers, + uint numProviders); + + [LibraryImport(RuntimeLibrary)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial void RhEventPipeInternal_Disable(ulong sessionID); + + [LibraryImport(RuntimeLibrary)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static unsafe partial IntPtr RhEventPipeInternal_CreateProvider(char* providerName, IntPtr callbackFunc, IntPtr callbackContext); + + [LibraryImport(RuntimeLibrary)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static unsafe partial IntPtr RhEventPipeInternal_DefineEvent( + IntPtr provHandle, + uint eventID, + long keywords, + uint eventVersion, + uint level, + void *pMetadata, + uint metadataLength); + + [LibraryImport(RuntimeLibrary)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static unsafe partial IntPtr RhEventPipeInternal_GetProvider(char* providerName); + + [LibraryImport(RuntimeLibrary)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial void RhEventPipeInternal_DeleteProvider(IntPtr provHandle); + + [LibraryImport(RuntimeLibrary)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static unsafe partial int RhEventPipeInternal_EventActivityIdControl(uint controlCode, Guid* activityId); + + [LibraryImport(RuntimeLibrary)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static unsafe partial void RhEventPipeInternal_WriteEventData( + IntPtr eventHandle, + void* pEventData, + uint dataCount, + Guid* activityId, + Guid* relatedActivityId); + + [LibraryImport(RuntimeLibrary)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static unsafe partial uint RhEventPipeInternal_GetSessionInfo(ulong sessionID, void* pSessionInfo); + + [LibraryImport(RuntimeLibrary)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static unsafe partial uint RhEventPipeInternal_GetNextEvent(ulong sessionID, void* pInstance); + + [LibraryImport(RuntimeLibrary)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial uint RhEventPipeInternal_SignalSession(ulong sessionID); + + [LibraryImport(RuntimeLibrary)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + internal static partial uint RhEventPipeInternal_WaitForSessionSignal(ulong sessionID, int timeoutMs); + +#endif // FEATURE_PERFTRACING + // // Interlocked helpers // diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs index 6a5cfdd79dbcf..ee3d499e85896 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs @@ -35,6 +35,8 @@ public static class Keywords private IncrementingPollingCounter? _allocRateCounter; private PollingCounter? _timerCounter; private PollingCounter? _fragmentationCounter; + +#if !NATIVEAOT // TODO private PollingCounter? _committedCounter; private IncrementingPollingCounter? _exceptionCounter; private PollingCounter? _gcTimeCounter; @@ -44,6 +46,8 @@ public static class Keywords private PollingCounter? _lohSizeCounter; private PollingCounter? _pohSizeCounter; private PollingCounter? _assemblyCounter; +#endif // !NATIVEAOT + private PollingCounter? _ilBytesJittedCounter; private PollingCounter? _methodsJittedCounter; private IncrementingPollingCounter? _jitTimeCounter; @@ -100,6 +104,8 @@ protected override void OnEventCommand(EventCommandEventArgs command) var gcInfo = GC.GetGCMemoryInfo(); return gcInfo.HeapSizeBytes != 0 ? gcInfo.FragmentedBytes * 100d / gcInfo.HeapSizeBytes : 0; }) { DisplayName = "GC Fragmentation", DisplayUnits = "%" }; + +#if !NATIVEAOT // TODO _committedCounter ??= new PollingCounter("gc-committed", this, () => ((double)GC.GetGCMemoryInfo().TotalCommittedBytes / 1_000_000)) { DisplayName = "GC Committed Bytes", DisplayUnits = "MB" }; _exceptionCounter ??= new IncrementingPollingCounter("exception-count", this, () => Exception.GetExceptionCount()) { DisplayName = "Exception Count", DisplayRateTimeScale = new TimeSpan(0, 0, 1) }; _gcTimeCounter ??= new PollingCounter("time-in-gc", this, () => GC.GetLastGCPercentTimeInGC()) { DisplayName = "% Time in GC since last GC", DisplayUnits = "%" }; @@ -109,6 +115,8 @@ protected override void OnEventCommand(EventCommandEventArgs command) _lohSizeCounter ??= new PollingCounter("loh-size", this, () => GC.GetGenerationSize(3)) { DisplayName = "LOH Size", DisplayUnits = "B" }; _pohSizeCounter ??= new PollingCounter("poh-size", this, () => GC.GetGenerationSize(4)) { DisplayName = "POH (Pinned Object Heap) Size", DisplayUnits = "B" }; _assemblyCounter ??= new PollingCounter("assembly-count", this, () => System.Reflection.Assembly.GetAssemblyCount()) { DisplayName = "Number of Assemblies Loaded" }; +#endif // !NATIVEAOT + _ilBytesJittedCounter ??= new PollingCounter("il-bytes-jitted", this, () => System.Runtime.JitInfo.GetCompiledILBytes()) { DisplayName = "IL Bytes Jitted", DisplayUnits = "B" }; _methodsJittedCounter ??= new PollingCounter("methods-jitted-count", this, () => System.Runtime.JitInfo.GetCompiledMethodCount()) { DisplayName = "Number of Methods Jitted" }; _jitTimeCounter ??= new IncrementingPollingCounter("time-in-jit", this, () => System.Runtime.JitInfo.GetCompilationTime().TotalMilliseconds) { DisplayName = "Time spent in JIT", DisplayUnits = "ms", DisplayRateTimeScale = new TimeSpan(0, 0, 1) }; diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Overlapped.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Overlapped.cs index 29446e444073c..a97bf7464ec3b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Overlapped.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Overlapped.cs @@ -185,9 +185,11 @@ public static void Free(NativeOverlapped* nativeOverlappedPtr) #if FEATURE_PERFTRACING #if !((TARGET_BROWSER || TARGET_WASI) && !FEATURE_WASM_THREADS) +#if !NATIVEAOT if (NativeRuntimeEventSource.Log.IsEnabled()) NativeRuntimeEventSource.Log.ThreadPoolIOPack(pNativeOverlapped); #endif +#endif #endif NativeOverlapped* pRet = pNativeOverlapped; From a4ee746dbfcb48b3a342a2022f0110bb903e17f7 Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Mon, 9 Jan 2023 10:19:36 -0800 Subject: [PATCH 07/32] build artifacts --- src/coreclr/nativeaot/Directory.Build.props | 5 + src/coreclr/nativeaot/Runtime/CMakeLists.txt | 142 ++++++++++++++++++ .../nativeaot/Runtime/Full/CMakeLists.txt | 22 +++ 3 files changed, 169 insertions(+) diff --git a/src/coreclr/nativeaot/Directory.Build.props b/src/coreclr/nativeaot/Directory.Build.props index 94ee1363ee0fa..8bed9ddc84653 100644 --- a/src/coreclr/nativeaot/Directory.Build.props +++ b/src/coreclr/nativeaot/Directory.Build.props @@ -4,6 +4,10 @@ false + + + true + false @@ -39,6 +43,7 @@ NATIVEAOT;NETCOREAPP + $(DefineConstants);FEATURE_PERFTRACING true diff --git a/src/coreclr/nativeaot/Runtime/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/CMakeLists.txt index 290deac1531e2..60327be2d9666 100644 --- a/src/coreclr/nativeaot/Runtime/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/CMakeLists.txt @@ -1,3 +1,143 @@ +# These need to happen before the VM and debug-pal includes. +set(EP_GENERATED_HEADER_PATH "${GENERATED_INCLUDE_DIR}") +include (${CLR_SRC_NATIVE_DIR}/eventpipe/configure.cmake) +include_directories(${EP_GENERATED_HEADER_PATH}) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(AOT_EVENTPIPE_SHIM_DIR "${CMAKE_CURRENT_SOURCE_DIR}/eventpipe") + +set (SHARED_EVENTPIPE_SOURCE_DIR "${CLR_SRC_NATIVE_DIR}/eventpipe") +include_directories(${SHARED_EVENTPIPE_SOURCE_DIR}) + +set (AOT_EVENTPIPE_SHIM_SOURCES "") +set (AOT_EVENTPIPE_SHIM_HEADERS "") +set (AOT_EVENTPIPE_MANAGED_TO_NATIVE_SOURCES "") +set (SHARED_EVENTPIPE_SOURCES "") +set (SHARED_EVENTPIPE_HEADERS "") +set (SHARED_DIAGNOSTIC_SERVER_SOURCES "") +set (SHARED_DIAGNOSTIC_SERVER_HEADERS "") +set (AOT_EVENTPIPE_DISABLED_SOURCES "") + +list(APPEND SHARED_EVENTPIPE_SOURCES + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-sources.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-block.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-buffer.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-buffer-manager.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-config.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event-instance.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event-payload.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event-source.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-file.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-json-file.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-metadata-generator.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-provider.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-sample-profiler.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-session.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-session-provider.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-stack-contents.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-stream.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-thread.c +) + +list(APPEND SHARED_EVENTPIPE_HEADERS + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-block.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-buffer.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-buffer-manager.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-config.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-config-internals.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event-instance.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event-payload.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event-source.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-file.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-getter-setter.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-ipc-pal-types.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-ipc-pal-types-forward.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-ipc-stream.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-json-file.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-metadata-generator.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-provider.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-provider-internals.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-rt.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-rt-config.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-rt-types.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-sample-profiler.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-session.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-session-provider.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-stack-contents.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-stream.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-thread.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-types.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-types-forward.h +) + +list(APPEND SHARED_DIAGNOSTIC_SERVER_SOURCES + ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-sources.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-dump-protocol.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-eventpipe-protocol.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-ipc-pal-namedpipe.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-ipc.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-process-protocol.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-profiler-protocol.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-protocol.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-server.c +) + +list(APPEND SHARED_DIAGNOSTIC_SERVER_HEADERS + ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-dump-protocol.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-eventpipe-protocol.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-getter-setter.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-ipc.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-ipc-pal.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-ipc-pal-types.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-ipc-pal-namedpipe.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-process-protocol.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-profiler-protocol.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-protocol.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-rt.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-rt-config.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-rt-types.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-server.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-types.h +) + +list(APPEND AOT_EVENTPIPE_SHIM_SOURCES + ${AOT_EVENTPIPE_SHIM_DIR}/ep-rt-aot.cpp +) + +list(APPEND AOT_EVENTPIPE_SHIM_HEADERS + ${AOT_EVENTPIPE_SHIM_DIR}/ds-rt-aot.h + ${AOT_EVENTPIPE_SHIM_DIR}/ds-rt-types-aot.h + ${AOT_EVENTPIPE_SHIM_DIR}/ep-rt-aot.h + ${AOT_EVENTPIPE_SHIM_DIR}/ep-rt-config-aot.h + ${AOT_EVENTPIPE_SHIM_DIR}/ep-rt-types-aot.h +) + +list(APPEND AOT_EVENTPIPE_MANAGED_TO_NATIVE_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/eventpipeinternal.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/eventpipeadapter.h + ${CMAKE_CURRENT_SOURCE_DIR}/diagnosticserveradapter.h + ${CMAKE_CURRENT_SOURCE_DIR}/AotEnabledEventPipeInterface.cpp +) + +list(APPEND EVENTPIPE_SOURCES + ${AOT_EVENTPIPE_SHIM_SOURCES} + ${AOT_EVENTPIPE_SHIM_HEADERS} + ${AOT_EVENTPIPE_MANAGED_TO_NATIVE_SOURCES} + ${SHARED_EVENTPIPE_SOURCES} + ${SHARED_EVENTPIPE_HEADERS} + ${SHARED_DIAGNOSTIC_SERVER_SOURCES} + ${SHARED_DIAGNOSTIC_SERVER_HEADERS} + ${SHARED_EVENTPIPE_CONFIG_HEADERS} +) + +list(APPEND AOT_EVENTPIPE_DISABLED_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/AotDisabledEventPipeInterface.cpp +) + set(GC_DIR ../../gc) set(COMMON_RUNTIME_SOURCES @@ -37,6 +177,8 @@ set(COMMON_RUNTIME_SOURCES UniversalTransitionHelpers.cpp yieldprocessornormalized.cpp + EventPipeInterface.h + ${GC_DIR}/gceventstatus.cpp ${GC_DIR}/gcload.cpp ${GC_DIR}/gcconfig.cpp diff --git a/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt index 22af5f44eba20..1ff33f6da241a 100644 --- a/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt @@ -24,6 +24,9 @@ add_library(Runtime.WorkstationGC STATIC ${COMMON_RUNTIME_SOURCES} ${FULL_RUNTIM add_library(Runtime.ServerGC STATIC ${COMMON_RUNTIME_SOURCES} ${FULL_RUNTIME_SOURCES} ${RUNTIME_SOURCES_ARCH_ASM} ${SERVER_GC_SOURCES} ${RUNTIME_ARCH_ASM_OBJECTS}) +add_library(Aot.EventPipe STATIC ${EVENTPIPE_SOURCES}) +add_library(Aot.Disabled.EventPipe STATIC ${AOT_EVENTPIPE_DISABLED_SOURCES}) + target_compile_definitions(Runtime.ServerGC PRIVATE -DFEATURE_SVR_GC) if (CLR_CMAKE_TARGET_WIN32) @@ -63,6 +66,23 @@ add_custom_command( set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/AsmOffsets.inc" PROPERTIES GENERATED TRUE) +set_source_files_properties(${SHARED_EVENTPIPE_SOURCES} PROPERTIES LANGUAGE CXX) +set_source_files_properties(${SHARED_DIAGNOSTIC_SERVER_SOURCES} PROPERTIES LANGUAGE CXX) + +if(CLR_CMAKE_HOST_UNIX) + if (CMAKE_VERSION VERSION_GREATER 3.11 OR CMAKE_VERSION VERSION_EQUAL 3.11) + set_source_files_properties(${SHARED_EVENTPIPE_SOURCES} PROPERTIES COMPILE_OPTIONS -xc++) + set_source_files_properties(${SHARED_DIAGNOSTIC_SERVER_SOURCES} PROPERTIES COMPILE_OPTIONS -xc++) + endif() +endif(CLR_CMAKE_HOST_UNIX) + +add_definitions(-DFEATURE_PERFTRACING) + +if (WIN32) + set_source_files_properties(${SHARED_EVENTPIPE_SOURCES} PROPERTIES COMPILE_FLAGS "/FI\"${RUNTIME_DIR}/eventpipe/NativeaotEventPipeSupport.h\"") + set_source_files_properties(${SHARED_DIAGNOSTIC_SERVER_SOURCES} PROPERTIES COMPILE_FLAGS "/FI\"${RUNTIME_DIR}/eventpipe/NativeaotEventPipeSupport.h\"") +endif() + # Runtime.WorkstationGC and Runtime.ServerGC share AsmOffsets.inc and assembler helpers (for Windows ARM/ARM64). # Avoid a race condition by adding this target as a dependency for both libraries. add_custom_target( @@ -78,6 +98,8 @@ endif (CLR_CMAKE_TARGET_WIN32) install_static_library(Runtime.WorkstationGC aotsdk nativeaot) install_static_library(Runtime.ServerGC aotsdk nativeaot) +install_static_library(Aot.EventPipe aotsdk nativeaot) +install_static_library(Aot.Disabled.EventPipe aotsdk nativeaot) if (CLR_CMAKE_TARGET_WIN32) install_static_library(Runtime.ServerGC.GuardCF aotsdk nativeaot) endif (CLR_CMAKE_TARGET_WIN32) From fe8252c54a10b8ed5c0c39178619fe65f8ac77f7 Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Mon, 9 Jan 2023 10:39:52 -0800 Subject: [PATCH 08/32] required changes to NativeAOT to support EP --- src/coreclr/nativeaot/Runtime/CommonMacros.h | 8 ++++++-- .../nativeaot/Runtime/CommonMacros.inl | 8 ++++++-- src/coreclr/nativeaot/Runtime/PalRedhawk.h | 20 ++++++++++++++++--- src/coreclr/nativeaot/Runtime/loglf.h | 2 ++ src/coreclr/nativeaot/Runtime/thread.h | 4 ++-- .../nativeaot/Runtime/unix/PalRedhawkUnix.cpp | 5 +++++ .../Runtime/windows/PalRedhawkMinWin.cpp | 5 +++++ 7 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/coreclr/nativeaot/Runtime/CommonMacros.h b/src/coreclr/nativeaot/Runtime/CommonMacros.h index a4a82be3753e5..98dff271dff45 100644 --- a/src/coreclr/nativeaot/Runtime/CommonMacros.h +++ b/src/coreclr/nativeaot/Runtime/CommonMacros.h @@ -62,7 +62,11 @@ #endif #endif -#ifndef __GCENV_BASE_INCLUDED__ +// TODO: gcenv.base.h provides these definitions only if it has been included and windows.h +// has not been included (even though though windows.h does not define these services); in +// all other cases the services need to be defined here. + +#if !(defined(__GCENV_BASE_INCLUDED__) && !defined(_INC_WINDOWS)) // // This macro returns val rounded up as necessary to be a multiple of alignment; alignment must be a power of 2 @@ -75,7 +79,7 @@ inline uintptr_t ALIGN_DOWN(uintptr_t val, uintptr_t alignment); template inline T* ALIGN_DOWN(T* val, uintptr_t alignment); -#endif // !__GCENV_BASE_INCLUDED__ +#endif // !(defined(__GCENV_BASE_INCLUDED__) && !defined(_INC_WINDOWS)) inline bool IS_ALIGNED(uintptr_t val, uintptr_t alignment); template diff --git a/src/coreclr/nativeaot/Runtime/CommonMacros.inl b/src/coreclr/nativeaot/Runtime/CommonMacros.inl index a9ad0b2b6764e..b37eab9d55079 100644 --- a/src/coreclr/nativeaot/Runtime/CommonMacros.inl +++ b/src/coreclr/nativeaot/Runtime/CommonMacros.inl @@ -1,7 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#ifndef __GCENV_BASE_INCLUDED__ +// TODO: gcenv.base.h provides these definitions only if it has been included and windows.h +// has not been included (even though though windows.h does not define these services); in +// all other cases the services need to be defined here. + +#if !(defined(__GCENV_BASE_INCLUDED__) && !defined(_INC_WINDOWS)) // // This macro returns val rounded up as necessary to be a multiple of alignment; alignment must be a power of 2 @@ -36,7 +40,7 @@ inline T* ALIGN_DOWN(T* val, uintptr_t alignment) return reinterpret_cast(ALIGN_DOWN(reinterpret_cast(val), alignment)); } -#endif // !__GCENV_BASE_INCLUDED__ +#endif // !(defined(__GCENV_BASE_INCLUDED__) && !defined(_INC_WINDOWS)) inline bool IS_ALIGNED(uintptr_t val, uintptr_t alignment) { diff --git a/src/coreclr/nativeaot/Runtime/PalRedhawk.h b/src/coreclr/nativeaot/Runtime/PalRedhawk.h index 6b14fcb2b20cc..0188a26868ed8 100644 --- a/src/coreclr/nativeaot/Runtime/PalRedhawk.h +++ b/src/coreclr/nativeaot/Runtime/PalRedhawk.h @@ -49,6 +49,9 @@ #endif // !_MSC_VER +// defined in gcrhenv.cpp +bool __SwitchToThread(uint32_t dwSleepMSec, uint32_t dwSwitchCount); + #ifndef _INC_WINDOWS //#ifndef DACCESS_COMPILE @@ -101,9 +104,6 @@ typedef struct _GUID { #define DECLARE_HANDLE(_name) typedef HANDLE _name -// defined in gcrhenv.cpp -bool __SwitchToThread(uint32_t dwSleepMSec, uint32_t dwSwitchCount); - struct FILETIME { uint32_t dwLowDateTime; @@ -602,6 +602,19 @@ extern uint32_t g_RhNumberOfProcessors; #endif // !_INC_WINDOWS #endif // !DACCESS_COMPILE +// TODO: Duplicate the definition from PalRedhawkFunctions.h to allow the EventPipe code to +// access PalEventWrite even though the PalRedhawkFunctions.h services are generally not +// available in NativeAOT runtime contexts where windows.h has been included. +#ifdef _INC_WINDOWS +#ifdef BUILDING_SHARED_NATIVEAOT_EVENTPIPE_CODE +extern "C" uint32_t __stdcall EventWrite(REGHANDLE, const EVENT_DESCRIPTOR *, uint32_t, EVENT_DATA_DESCRIPTOR *); +inline uint32_t PalEventWrite(REGHANDLE arg1, const EVENT_DESCRIPTOR * arg2, uint32_t arg3, EVENT_DATA_DESCRIPTOR * arg4) +{ + return EventWrite(arg1, arg2, arg3, arg4); +} +#endif // BUILDING_SHARED_NATIVEAOT_EVENTPIPE_CODE +#endif // _INC_WINDOWS + // The Redhawk PAL must be initialized before any of its exports can be called. Returns true for a successful // initialization and false on failure. REDHAWK_PALIMPORT bool REDHAWK_PALAPI PalInit(); @@ -716,6 +729,7 @@ REDHAWK_PALIMPORT void* REDHAWK_PALAPI PalAddVectoredExceptionHandler(uint32_t f typedef uint32_t (__stdcall *BackgroundCallback)(_In_opt_ void* pCallbackContext); REDHAWK_PALIMPORT bool REDHAWK_PALAPI PalStartBackgroundGCThread(_In_ BackgroundCallback callback, _In_opt_ void* pCallbackContext); REDHAWK_PALIMPORT bool REDHAWK_PALAPI PalStartFinalizerThread(_In_ BackgroundCallback callback, _In_opt_ void* pCallbackContext); +REDHAWK_PALIMPORT bool REDHAWK_PALAPI PalStartEventPipeHelperThread(_In_ BackgroundCallback callback, _In_opt_ void* pCallbackContext); typedef void (*PalHijackCallback)(_In_ NATIVE_CONTEXT* pThreadContext, _In_opt_ void* pThreadToHijack); REDHAWK_PALIMPORT void REDHAWK_PALAPI PalHijack(HANDLE hThread, _In_opt_ void* pThreadToHijack); diff --git a/src/coreclr/nativeaot/Runtime/loglf.h b/src/coreclr/nativeaot/Runtime/loglf.h index ff6abd88b9ff7..a3752fb167e67 100644 --- a/src/coreclr/nativeaot/Runtime/loglf.h +++ b/src/coreclr/nativeaot/Runtime/loglf.h @@ -10,8 +10,10 @@ DEFINE_LOG_FACILITY(LF_GCALLOC ,0x00000004) DEFINE_LOG_FACILITY(LF_GCROOTS ,0x00000008) DEFINE_LOG_FACILITY(LF_STARTUP ,0x00000010) // Log startup and shutdown failures DEFINE_LOG_FACILITY(LF_STACKWALK ,0x00000020) +DEFINE_LOG_FACILITY(LF_DIAGNOSTICS_PORT, 0x00000040) // LF_ALWAYS 0x80000000 // make certain you don't try to use this bit for a real facility // LF_ALL 0xFFFFFFFF // #undef DEFINE_LOG_FACILITY +#define INFINITE 0xFFFFFFFF // Infinite timeout diff --git a/src/coreclr/nativeaot/Runtime/thread.h b/src/coreclr/nativeaot/Runtime/thread.h index 698d88abab485..4e657c8f171a9 100644 --- a/src/coreclr/nativeaot/Runtime/thread.h +++ b/src/coreclr/nativeaot/Runtime/thread.h @@ -331,10 +331,10 @@ typedef DacScanCallbackData EnumGcRefScanContext; typedef void EnumGcRefCallbackFunc(PTR_PTR_Object, EnumGcRefScanContext* callbackData, uint32_t flags); #else // DACCESS_COMPILE -#ifndef __GCENV_BASE_INCLUDED__ +#if !(defined(__GCENV_BASE_INCLUDED__) && !defined(FEATURE_PERFTRACING)) struct ScanContext; typedef void promote_func(PTR_PTR_Object, ScanContext*, unsigned); -#endif // !__GCENV_BASE_INCLUDED__ +#endif // !__GCENV_BASE_INCLUDED__ && FEATURE_PERFTRACING typedef promote_func EnumGcRefCallbackFunc; typedef ScanContext EnumGcRefScanContext; diff --git a/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp b/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp index 2893bc6289758..8921e7b019be6 100644 --- a/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp +++ b/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp @@ -632,6 +632,11 @@ REDHAWK_PALEXPORT bool REDHAWK_PALAPI PalStartFinalizerThread(_In_ BackgroundCal #endif // HOST_WASM } +REDHAWK_PALEXPORT bool REDHAWK_PALAPI PalStartEventPipeHelperThread(_In_ BackgroundCallback callback, _In_opt_ void* pCallbackContext) +{ + return PalStartBackgroundWork(callback, pCallbackContext, UInt32_FALSE); +} + // Returns a 64-bit tick count with a millisecond resolution. It tries its best // to return monotonically increasing counts and avoid being affected by changes // to the system clock (either due to drift or due to explicit changes to system diff --git a/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp b/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp index 8e8b85356b28d..8ce4fbdecc2bb 100644 --- a/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp +++ b/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp @@ -612,6 +612,11 @@ REDHAWK_PALEXPORT bool REDHAWK_PALAPI PalStartFinalizerThread(_In_ BackgroundCal return PalStartBackgroundWork(callback, pCallbackContext, TRUE); } +REDHAWK_PALEXPORT bool REDHAWK_PALAPI PalStartEventPipeHelperThread(_In_ BackgroundCallback callback, _In_opt_ void* pCallbackContext) +{ + return PalStartBackgroundWork(callback, pCallbackContext, FALSE); +} + REDHAWK_PALEXPORT bool REDHAWK_PALAPI PalEventEnabled(REGHANDLE regHandle, _In_ const EVENT_DESCRIPTOR* eventDescriptor) { return !!EventEnabled(regHandle, eventDescriptor); From 4b9e1033815348e1ce628049a225482a34d3f4d4 Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Mon, 9 Jan 2023 10:44:24 -0800 Subject: [PATCH 09/32] changes to common EP source --- src/native/eventpipe/ds-ipc-pal-namedpipe.h | 3 ++ src/native/eventpipe/ep-json-file.c | 4 ++- src/native/eventpipe/ep-rt-config.h | 31 +++++++++++++++++++-- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/native/eventpipe/ds-ipc-pal-namedpipe.h b/src/native/eventpipe/ds-ipc-pal-namedpipe.h index 6952ccc17aca5..fec28bcd1ccce 100644 --- a/src/native/eventpipe/ds-ipc-pal-namedpipe.h +++ b/src/native/eventpipe/ds-ipc-pal-namedpipe.h @@ -1,6 +1,9 @@ #ifndef __DIAGNOSTICS_IPC_PAL_NAMEDPIPE_H__ #define __DIAGNOSTICS_IPC_PAL_NAMEDPIPE_H__ +#undef __AOT_WINDOWS_DEF_NOT_NEEDED___ +#define __AOT_WINDOWS_DEF_NOT_NEEDED___ + #include "ds-rt-config.h" #ifdef ENABLE_PERFTRACING diff --git a/src/native/eventpipe/ep-json-file.c b/src/native/eventpipe/ep-json-file.c index 52e5011e3d08a..57e62961c24fc 100644 --- a/src/native/eventpipe/ep-json-file.c +++ b/src/native/eventpipe/ep-json-file.c @@ -141,7 +141,9 @@ ep_json_file_write_event_data ( json_file_write_string (json_file, buffer); } - characters_written = ep_rt_utf8_string_snprintf (buffer, ARRAY_SIZE (buffer), "\"Thread (%" PRIu64 ")\"]},", ep_rt_thread_id_t_to_uint64_t (thread_id)); + // TODO: AOT Event Port, PRIu64 changed to + //characters_written = ep_rt_utf8_string_snprintf (buffer, ARRAY_SIZE (buffer), "\"Thread (%" PRIu64 ")\"]},", ep_rt_thread_id_t_to_uint64_t (thread_id)); + characters_written = ep_rt_utf8_string_snprintf (buffer, ARRAY_SIZE (buffer), "\"%lu\",\n]},", ep_rt_thread_id_t_to_uint64_t (thread_id)); if (characters_written > 0 && characters_written < (int32_t)ARRAY_SIZE (buffer)) json_file_write_string (json_file, buffer); } diff --git a/src/native/eventpipe/ep-rt-config.h b/src/native/eventpipe/ep-rt-config.h index 4d5a6cc98c1c2..ea4475227339a 100644 --- a/src/native/eventpipe/ep-rt-config.h +++ b/src/native/eventpipe/ep-rt-config.h @@ -1,9 +1,9 @@ #ifndef __EVENTPIPE_RT_CONFIG_H__ #define __EVENTPIPE_RT_CONFIG_H__ -#include "ep-shared-config.h" +#include -#ifndef FEATURE_CORECLR +#if !defined(FEATURE_CORECLR) && !defined(FEATURE_NATIVEAOT) #include @@ -16,7 +16,7 @@ #define DS_RT_H #define DS_RT_TYPES_H -#else /* !FEATURE_CORECLR */ +#elif defined(FEATURE_CORECLR) #ifndef EP_NO_RT_DEPENDENCY #include "common.h" @@ -43,6 +43,31 @@ #define DS_RT_H "ds-rt-coreclr.h" #define DS_RT_TYPES_H "ds-rt-types-coreclr.h" +#elif defined(FEATURE_NATIVEAOT) + +#ifndef EP_NO_RT_DEPENDENCY +#include "common.h" +#endif + +#if defined(FEATURE_PERFTRACING) +#define ENABLE_PERFTRACING +#endif + +#ifdef TARGET_WINDOWS +#define HOST_WIN32 +#endif + +#if defined(FEATURE_PERFTRACING) && defined(FEATURE_PROFAPI_ATTACH_DETACH) && defined(DACCESS_COMPILE) +#undef FEATURE_PROFAPI_ATTACH_DETACH +#endif + +#define EP_RT_H +#define EP_RT_TYPES_H +#define EP_RT_CONFIG_H + +#define DS_RT_H +#define DS_RT_TYPES_H + #endif #ifndef EP_NO_RT_DEPENDENCY From 548e8d70c832cbcf4e4e8f2abb207c25940f93dd Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Mon, 9 Jan 2023 10:48:40 -0800 Subject: [PATCH 10/32] sample EventSource test app --- .../tools/aot/ILCompiler/repro/Program.cs | 50 +++++++++++++++++-- .../tools/aot/ILCompiler/repro/repro.csproj | 3 +- .../reproNative/reproNative.vcxproj | 2 +- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/coreclr/tools/aot/ILCompiler/repro/Program.cs b/src/coreclr/tools/aot/ILCompiler/repro/Program.cs index 9e71394c3732a..e3aed34c2f487 100644 --- a/src/coreclr/tools/aot/ILCompiler/repro/Program.cs +++ b/src/coreclr/tools/aot/ILCompiler/repro/Program.cs @@ -1,12 +1,52 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; - -class Program +namespace EP_Target { - static void Main() + using System; + using System.Diagnostics.Tracing; + using System.Threading; + + public static class Program + { + public static void Main(string[] args) + { + Console.WriteLine("Waiting 10 seconds to client to get the PID"); + Thread.Sleep(10 * 1000); + + TargetStartLogging(); + + Console.WriteLine("Done done!"); + } + + private static void TargetStartLogging() + { + DemoEventSource.Log.AppStarted("Hello World From .NET!", 12); + } + } + + [EventSource(Name = "Demo")] + class DemoEventSource : EventSource { - Console.WriteLine("Hello world"); + public static DemoEventSource Log { get; } = new DemoEventSource(); + + [Event(1, Keywords = Keywords.Startup)] + public void AppStarted(string message, int favoriteNumber) => WriteEvent(1, message, favoriteNumber); + + [Event(2, Keywords = Keywords.Requests)] + public void RequestStart(int requestId) => WriteEvent(2, requestId); + + [Event(3, Keywords = Keywords.Requests)] + public void RequestStop(int requestId) => WriteEvent(3, requestId); + + [Event(4, Keywords = Keywords.Startup, Level = EventLevel.Verbose)] + public void DebugMessage(string message) => WriteEvent(4, message); + + + public class Keywords + { + public const EventKeywords Startup = (EventKeywords)0x0001; + public const EventKeywords Requests = (EventKeywords)0x0002; + } } } diff --git a/src/coreclr/tools/aot/ILCompiler/repro/repro.csproj b/src/coreclr/tools/aot/ILCompiler/repro/repro.csproj index b3a490ed6c078..1787116202c08 100644 --- a/src/coreclr/tools/aot/ILCompiler/repro/repro.csproj +++ b/src/coreclr/tools/aot/ILCompiler/repro/repro.csproj @@ -11,6 +11,7 @@ true false false + true - + diff --git a/src/coreclr/tools/aot/ILCompiler/reproNative/reproNative.vcxproj b/src/coreclr/tools/aot/ILCompiler/reproNative/reproNative.vcxproj index ee8d32964d805..83334d3b2e9cf 100644 --- a/src/coreclr/tools/aot/ILCompiler/reproNative/reproNative.vcxproj +++ b/src/coreclr/tools/aot/ILCompiler/reproNative/reproNative.vcxproj @@ -81,7 +81,7 @@ Console true - $(ArtifactsRoot)bin\repro\x64\Debug\repro.obj;$(Win32SDKLibs);%(AdditionalDependencies);$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\Runtime.WorkstationGC.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\System.Globalization.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\System.IO.Compression.Native.Aot.lib + $(ArtifactsRoot)bin\repro\x64\Debug\repro.obj;$(Win32SDKLibs);%(AdditionalDependencies);$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\Runtime.WorkstationGC.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\System.Globalization.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\System.IO.Compression.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\Aot.EventPipe.lib; From 1a742b0ef04fb639fe74d8eaa0f68ac5a883d7cb Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Wed, 11 Jan 2023 15:50:54 -0800 Subject: [PATCH 11/32] Add EventPipe lib to the linker --- .../BuildIntegration/Microsoft.NETCore.Native.Unix.targets | 1 + .../BuildIntegration/Microsoft.NETCore.Native.Windows.targets | 1 + .../BuildIntegration/Microsoft.NETCore.Native.targets | 4 ++++ 3 files changed, 6 insertions(+) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets index 48c7a953c1883..6384275148a00 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets @@ -49,6 +49,7 @@ The .NET Foundation licenses this file to you under the MIT license. + diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets index fe5cdf1cd8638..fccc1c390b05e 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets @@ -33,6 +33,7 @@ The .NET Foundation licenses this file to you under the MIT license. + diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets index a44c06a0433e3..87e913bb0db5c 100755 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets @@ -95,6 +95,10 @@ The .NET Foundation licenses this file to you under the MIT license. $(FrameworkLibPath)\Framework$(LibFileExt) $(FrameworkLibPath)\libframework$(LibFileExt) SetupProperties + + Aot.Disabled.EventPipe + Aot.EventPipe + From a03fcb1d92011c77b423be12ba7dbcd360a2caae Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Thu, 12 Jan 2023 06:43:29 -0800 Subject: [PATCH 12/32] Additional conditions to include the EventPipe library --- .../nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets index 87e913bb0db5c..9e51cc57ba549 100755 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets @@ -97,7 +97,7 @@ The .NET Foundation licenses this file to you under the MIT license. SetupProperties Aot.Disabled.EventPipe - Aot.EventPipe + Aot.EventPipe From b36a06cb5bebf85ec8f288261daa40d7c4aaccff Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Thu, 12 Jan 2023 14:32:34 -0800 Subject: [PATCH 13/32] Fixing the Checked and Release and Linux builds --- .../Microsoft.NETCore.Native.Unix.targets | 4 ++++ .../Microsoft.NETCore.Native.Windows.targets | 2 ++ .../Microsoft.NETCore.Native.targets | 4 ---- .../nativeaot/Runtime/eventpipe/ep-rt-aot.h | 15 ++++++++++++++- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets index 6384275148a00..6998b38a6a104 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets @@ -42,6 +42,10 @@ The .NET Foundation licenses this file to you under the MIT license. $ORIGIN @executable_path + + libAot.Disabled.EventPipe + libAot.EventPipe + diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets index fccc1c390b05e..6cae54ea5cbbd 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets @@ -25,6 +25,8 @@ The .NET Foundation licenses this file to you under the MIT license. wmainCRTStartup WINDOWS CONSOLE + Aot.Disabled.EventPipe + Aot.EventPipe diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets index 9e51cc57ba549..a44c06a0433e3 100755 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets @@ -95,10 +95,6 @@ The .NET Foundation licenses this file to you under the MIT license. $(FrameworkLibPath)\Framework$(LibFileExt) $(FrameworkLibPath)\libframework$(LibFileExt) SetupProperties - - Aot.Disabled.EventPipe - Aot.EventPipe - diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h index 2c39186d2e44e..359bc2236c91d 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h @@ -43,7 +43,20 @@ #define EP_NEVER_INLINE NOINLINE #undef EP_ALIGN_UP -#define EP_ALIGN_UP(val,align) ALIGN_UP(val,align) +#define EP_ALIGN_UP(val,align) _rt_aot_align_up(val,align) + +// TODO: The NativeAOT ALIGN_UP is defined in a tangled manner that generates linker errors if +// it is used here; instead, define a version tailored to the existing usage in the shared +// EventPipe code. +static inline uint8_t* _rt_aot_align_up(uint8_t* val, uintptr_t alignment) +{ + // alignment must be a power of 2 for this implementation to work (need modulo otherwise) + EP_ASSERT( 0 == (alignment & (alignment - 1)) ); + uintptr_t rawVal = reinterpret_cast(val); + uintptr_t result = (rawVal + (alignment - 1)) & ~(alignment - 1); + EP_ASSERT( result >= rawVal ); // check for overflow + return reinterpret_cast(result); +} #ifndef EP_RT_BUILD_TYPE_FUNC_NAME #define EP_RT_BUILD_TYPE_FUNC_NAME(prefix_name, type_name, func_name) \ From b152648477b2c66c29c02f0d66dc7088cec7b16f Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Sat, 14 Jan 2023 14:16:55 -0800 Subject: [PATCH 14/32] separating maanged and native EventSource switches --- .../Microsoft.NETCore.Native.Unix.targets | 2 +- .../Microsoft.NETCore.Native.Windows.targets | 2 +- src/coreclr/nativeaot/Runtime/CMakeLists.txt | 1 + .../Runtime/disabledeventpipeinternal.cpp | 113 ++++++++++++++++++ 4 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 src/coreclr/nativeaot/Runtime/disabledeventpipeinternal.cpp diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets index b6abc249502a1..2891b0dd96267 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets @@ -44,7 +44,7 @@ The .NET Foundation licenses this file to you under the MIT license. @executable_path libAot.Disabled.EventPipe - libAot.EventPipe + libAot.EventPipe diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets index 6cae54ea5cbbd..5a1d877b2c832 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets @@ -26,7 +26,7 @@ The .NET Foundation licenses this file to you under the MIT license. WINDOWS CONSOLE Aot.Disabled.EventPipe - Aot.EventPipe + Aot.EventPipe diff --git a/src/coreclr/nativeaot/Runtime/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/CMakeLists.txt index 60327be2d9666..3412a1801a8d7 100644 --- a/src/coreclr/nativeaot/Runtime/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/CMakeLists.txt @@ -136,6 +136,7 @@ list(APPEND EVENTPIPE_SOURCES list(APPEND AOT_EVENTPIPE_DISABLED_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/AotDisabledEventPipeInterface.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/disabledeventpipeinternal.cpp ) set(GC_DIR ../../gc) diff --git a/src/coreclr/nativeaot/Runtime/disabledeventpipeinternal.cpp b/src/coreclr/nativeaot/Runtime/disabledeventpipeinternal.cpp new file mode 100644 index 0000000000000..9a11d348b878e --- /dev/null +++ b/src/coreclr/nativeaot/Runtime/disabledeventpipeinternal.cpp @@ -0,0 +1,113 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "common.h" +#include "eventpipeadapter.h" + +#ifdef FEATURE_PERFTRACING + +struct EventPipeEventInstanceData +{ + void *ProviderID; + unsigned int EventID; + unsigned int ThreadID; + LARGE_INTEGER TimeStamp; + GUID ActivityId; + GUID RelatedActivityId; + const uint8_t *Payload; + unsigned int PayloadLength; +}; + +struct EventPipeSessionInfo +{ + FILETIME StartTimeAsUTCFileTime; + LARGE_INTEGER StartTimeStamp; + LARGE_INTEGER TimeStampFrequency; +}; + +EXTERN_C NATIVEAOT_API uint64_t __cdecl RhEventPipeInternal_Enable( + LPCWSTR outputFile, + EventPipeSerializationFormat format, + uint32_t circularBufferSizeInMB, + /* COR_PRF_EVENTPIPE_PROVIDER_CONFIG */ const void * pProviders, + uint32_t numProviders) +{ + __debugbreak(); + return 0; +} + +EXTERN_C NATIVEAOT_API void __cdecl RhEventPipeInternal_Disable(uint64_t sessionID) +{ + __debugbreak(); +} + +EXTERN_C NATIVEAOT_API intptr_t __cdecl RhEventPipeInternal_CreateProvider( + LPCWSTR providerName, + EventPipeCallback pCallbackFunc, + void* pCallbackContext) +{ + return 0; +} + +EXTERN_C NATIVEAOT_API intptr_t __cdecl RhEventPipeInternal_DefineEvent( + intptr_t provHandle, + uint32_t eventID, + int64_t keywords, + uint32_t eventVersion, + uint32_t level, + void *pMetadata, + uint32_t metadataLength) +{ + return 0; +} + +EXTERN_C NATIVEAOT_API intptr_t __cdecl RhEventPipeInternal_GetProvider(LPCWSTR providerName) +{ + __debugbreak(); + return 0; +} + +EXTERN_C NATIVEAOT_API void __cdecl RhEventPipeInternal_DeleteProvider(intptr_t provHandle) +{ +} + +EXTERN_C NATIVEAOT_API int __cdecl RhEventPipeInternal_EventActivityIdControl(uint32_t controlCode, GUID *pActivityId) +{ + __debugbreak(); + return 0; +} + +EXTERN_C NATIVEAOT_API void __cdecl RhEventPipeInternal_WriteEventData( + intptr_t eventHandle, + EventData *pEventData, + uint32_t eventDataCount, + const GUID * pActivityId, + const GUID * pRelatedActivityId) +{ +} + +EXTERN_C NATIVEAOT_API UInt32_BOOL __cdecl RhEventPipeInternal_GetSessionInfo(uint64_t sessionID, EventPipeSessionInfo *pSessionInfo) +{ + __debugbreak(); + return FALSE; +} + +EXTERN_C NATIVEAOT_API UInt32_BOOL __cdecl RhEventPipeInternal_GetNextEvent(uint64_t sessionID, EventPipeEventInstanceData *pInstance) +{ + __debugbreak(); + return FALSE; +} + +EXTERN_C NATIVEAOT_API UInt32_BOOL __cdecl RhEventPipeInternal_SignalSession(uint64_t sessionID) +{ + __debugbreak(); + return FALSE; +} + +EXTERN_C NATIVEAOT_API UInt32_BOOL __cdecl RhEventPipeInternal_WaitForSessionSignal(uint64_t sessionID, int32_t timeoutMs) +{ + __debugbreak(); + return FALSE; +} + +#endif // FEATURE_PERFTRACING From 28e54391f86824facb77431cf044c107145f4a1e Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Wed, 18 Jan 2023 15:31:10 -0800 Subject: [PATCH 15/32] Update src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Michal Strehovský --- .../BuildIntegration/Microsoft.NETCore.Native.Unix.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets index 2891b0dd96267..361763e13fc4c 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets @@ -43,7 +43,7 @@ The .NET Foundation licenses this file to you under the MIT license. $ORIGIN @executable_path - libAot.Disabled.EventPipe + libeventpipe-disabled libAot.EventPipe From fc77cb9234809a0786be333feb4027e0dd7a1753 Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Wed, 18 Jan 2023 18:03:50 -0800 Subject: [PATCH 16/32] FB, build break and test fixes --- .../Microsoft.NETCore.Native.Unix.targets | 6 +++--- .../Microsoft.NETCore.Native.Windows.targets | 4 ++-- src/coreclr/nativeaot/Runtime/CMakeLists.txt | 5 ++--- ...ntPipeInterface.cpp => DisabledEventPipeInterface.cpp} | 0 ...entPipeInterface.cpp => EnabledEventPipeInterface.cpp} | 0 src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt | 8 ++++---- src/coreclr/nativeaot/Runtime/eventpipeadapter.h | 4 ++++ src/coreclr/nativeaot/Runtime/eventpipeinternal.cpp | 6 +++--- .../tools/aot/ILCompiler/reproNative/reproNative.vcxproj | 2 +- ...ystem.Diagnostics.DiagnosticSource.NativeAotTests.proj | 2 +- src/native/eventpipe/ep-json-file.c | 8 ++++---- 11 files changed, 24 insertions(+), 21 deletions(-) rename src/coreclr/nativeaot/Runtime/{AotDisabledEventPipeInterface.cpp => DisabledEventPipeInterface.cpp} (100%) rename src/coreclr/nativeaot/Runtime/{AotEnabledEventPipeInterface.cpp => EnabledEventPipeInterface.cpp} (100%) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets index 361763e13fc4c..10d69d803f46c 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets @@ -40,11 +40,11 @@ The .NET Foundation licenses this file to you under the MIT license. $(CrossCompileArch)-linux-gnu $(CrossCompileArch)-alpine-linux-musl - $ORIGIN - @executable_path + $ORIGIN + @executable_path libeventpipe-disabled - libAot.EventPipe + libeventpipe-enabled diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets index 5a1d877b2c832..d8fffa5e642bd 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets @@ -25,8 +25,8 @@ The .NET Foundation licenses this file to you under the MIT license. wmainCRTStartup WINDOWS CONSOLE - Aot.Disabled.EventPipe - Aot.EventPipe + eventpipe-disabled + eventpipe-enabled diff --git a/src/coreclr/nativeaot/Runtime/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/CMakeLists.txt index 3412a1801a8d7..bbdd424ce8062 100644 --- a/src/coreclr/nativeaot/Runtime/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/CMakeLists.txt @@ -1,4 +1,3 @@ -# These need to happen before the VM and debug-pal includes. set(EP_GENERATED_HEADER_PATH "${GENERATED_INCLUDE_DIR}") include (${CLR_SRC_NATIVE_DIR}/eventpipe/configure.cmake) include_directories(${EP_GENERATED_HEADER_PATH}) @@ -120,7 +119,7 @@ list(APPEND AOT_EVENTPIPE_MANAGED_TO_NATIVE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/eventpipeinternal.cpp ${CMAKE_CURRENT_SOURCE_DIR}/eventpipeadapter.h ${CMAKE_CURRENT_SOURCE_DIR}/diagnosticserveradapter.h - ${CMAKE_CURRENT_SOURCE_DIR}/AotEnabledEventPipeInterface.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/EnabledEventPipeInterface.cpp ) list(APPEND EVENTPIPE_SOURCES @@ -135,7 +134,7 @@ list(APPEND EVENTPIPE_SOURCES ) list(APPEND AOT_EVENTPIPE_DISABLED_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/AotDisabledEventPipeInterface.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/DisabledEventPipeInterface.cpp ${CMAKE_CURRENT_SOURCE_DIR}/disabledeventpipeinternal.cpp ) diff --git a/src/coreclr/nativeaot/Runtime/AotDisabledEventPipeInterface.cpp b/src/coreclr/nativeaot/Runtime/DisabledEventPipeInterface.cpp similarity index 100% rename from src/coreclr/nativeaot/Runtime/AotDisabledEventPipeInterface.cpp rename to src/coreclr/nativeaot/Runtime/DisabledEventPipeInterface.cpp diff --git a/src/coreclr/nativeaot/Runtime/AotEnabledEventPipeInterface.cpp b/src/coreclr/nativeaot/Runtime/EnabledEventPipeInterface.cpp similarity index 100% rename from src/coreclr/nativeaot/Runtime/AotEnabledEventPipeInterface.cpp rename to src/coreclr/nativeaot/Runtime/EnabledEventPipeInterface.cpp diff --git a/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt index 1ff33f6da241a..be658ca8782df 100644 --- a/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt @@ -24,8 +24,8 @@ add_library(Runtime.WorkstationGC STATIC ${COMMON_RUNTIME_SOURCES} ${FULL_RUNTIM add_library(Runtime.ServerGC STATIC ${COMMON_RUNTIME_SOURCES} ${FULL_RUNTIME_SOURCES} ${RUNTIME_SOURCES_ARCH_ASM} ${SERVER_GC_SOURCES} ${RUNTIME_ARCH_ASM_OBJECTS}) -add_library(Aot.EventPipe STATIC ${EVENTPIPE_SOURCES}) -add_library(Aot.Disabled.EventPipe STATIC ${AOT_EVENTPIPE_DISABLED_SOURCES}) +add_library(eventpipe-enabled STATIC ${EVENTPIPE_SOURCES}) +add_library(eventpipe-disabled STATIC ${AOT_EVENTPIPE_DISABLED_SOURCES}) target_compile_definitions(Runtime.ServerGC PRIVATE -DFEATURE_SVR_GC) @@ -98,8 +98,8 @@ endif (CLR_CMAKE_TARGET_WIN32) install_static_library(Runtime.WorkstationGC aotsdk nativeaot) install_static_library(Runtime.ServerGC aotsdk nativeaot) -install_static_library(Aot.EventPipe aotsdk nativeaot) -install_static_library(Aot.Disabled.EventPipe aotsdk nativeaot) +install_static_library(eventpipe-enabled aotsdk nativeaot) +install_static_library(eventpipe-disabled aotsdk nativeaot) if (CLR_CMAKE_TARGET_WIN32) install_static_library(Runtime.ServerGC.GuardCF aotsdk nativeaot) endif (CLR_CMAKE_TARGET_WIN32) diff --git a/src/coreclr/nativeaot/Runtime/eventpipeadapter.h b/src/coreclr/nativeaot/Runtime/eventpipeadapter.h index 4f498bf664ae8..2d76e9aabcfdb 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipeadapter.h +++ b/src/coreclr/nativeaot/Runtime/eventpipeadapter.h @@ -239,6 +239,7 @@ class EventPipeAdapter final ep_rt_utf8_string_free (outputPathUTF8); return result; } +#endif // defined(NATIVEAOT_CORPROF_INCLUDE_IS_READY) static inline void Disable(EventPipeSessionID id) { @@ -253,6 +254,7 @@ class EventPipeAdapter final ep_disable(id); } +#if defined(NATIVEAOT_CORPROF_INCLUDE_IS_READY) static inline void StartStreaming(EventPipeSessionID id) { CONTRACTL @@ -328,6 +330,7 @@ class EventPipeAdapter final ep_add_provider_to_session (provider, session); } +#endif // defined(NATIVEAOT_CORPROF_INCLUDE_IS_READY) static inline EventPipeProvider * GetProvider (LPCWSTR providerName) { @@ -348,6 +351,7 @@ class EventPipeAdapter final return provider; } +#if defined(NATIVEAOT_CORPROF_INCLUDE_IS_READY) static EventPipeSessionProvider * CreateSessionProvider(const EventPipeProviderConfigurationAdapter &providerConfig) { CONTRACTL diff --git a/src/coreclr/nativeaot/Runtime/eventpipeinternal.cpp b/src/coreclr/nativeaot/Runtime/eventpipeinternal.cpp index 038fb1af281d4..06f16fc9c5c64 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipeinternal.cpp +++ b/src/coreclr/nativeaot/Runtime/eventpipeinternal.cpp @@ -38,7 +38,7 @@ EXTERN_C NATIVEAOT_API uint64_t __cdecl RhEventPipeInternal_Enable( EXTERN_C NATIVEAOT_API void __cdecl RhEventPipeInternal_Disable(uint64_t sessionID) { - __debugbreak(); + EventPipeAdapter::Disable(sessionID); } EXTERN_C NATIVEAOT_API intptr_t __cdecl RhEventPipeInternal_CreateProvider( @@ -71,8 +71,8 @@ EXTERN_C NATIVEAOT_API intptr_t __cdecl RhEventPipeInternal_DefineEvent( EXTERN_C NATIVEAOT_API intptr_t __cdecl RhEventPipeInternal_GetProvider(LPCWSTR providerName) { - __debugbreak(); - return 0; + EventPipeProvider* pProvider = EventPipeAdapter::GetProvider(providerName); + return reinterpret_cast(pProvider); } EXTERN_C NATIVEAOT_API void __cdecl RhEventPipeInternal_DeleteProvider(intptr_t provHandle) diff --git a/src/coreclr/tools/aot/ILCompiler/reproNative/reproNative.vcxproj b/src/coreclr/tools/aot/ILCompiler/reproNative/reproNative.vcxproj index 83334d3b2e9cf..f2f9dcb9935f3 100644 --- a/src/coreclr/tools/aot/ILCompiler/reproNative/reproNative.vcxproj +++ b/src/coreclr/tools/aot/ILCompiler/reproNative/reproNative.vcxproj @@ -81,7 +81,7 @@ Console true - $(ArtifactsRoot)bin\repro\x64\Debug\repro.obj;$(Win32SDKLibs);%(AdditionalDependencies);$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\Runtime.WorkstationGC.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\System.Globalization.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\System.IO.Compression.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\Aot.EventPipe.lib; + $(ArtifactsRoot)bin\repro\x64\Debug\repro.obj;$(Win32SDKLibs);%(AdditionalDependencies);$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\Runtime.WorkstationGC.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\System.Globalization.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\System.IO.Compression.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\eventPipe-enabled.lib; diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/System.Diagnostics.DiagnosticSource.NativeAotTests.proj b/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/System.Diagnostics.DiagnosticSource.NativeAotTests.proj index 8001203352b58..ec8c46ce38663 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/System.Diagnostics.DiagnosticSource.NativeAotTests.proj +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/System.Diagnostics.DiagnosticSource.NativeAotTests.proj @@ -3,7 +3,7 @@ + EnabledProperties="EventSourceSupport;EnableNativeEventPipe" /> diff --git a/src/native/eventpipe/ep-json-file.c b/src/native/eventpipe/ep-json-file.c index 57e62961c24fc..4f4ad65c1a0a5 100644 --- a/src/native/eventpipe/ep-json-file.c +++ b/src/native/eventpipe/ep-json-file.c @@ -12,7 +12,9 @@ #ifdef HAVE_INTTYPES_H #include #else -#ifndef PRIu64 +#if defined(TARGET_UNIX) +#define PRIu64 "lu" +#else #define PRIu64 "llu" #endif #endif @@ -141,9 +143,7 @@ ep_json_file_write_event_data ( json_file_write_string (json_file, buffer); } - // TODO: AOT Event Port, PRIu64 changed to - //characters_written = ep_rt_utf8_string_snprintf (buffer, ARRAY_SIZE (buffer), "\"Thread (%" PRIu64 ")\"]},", ep_rt_thread_id_t_to_uint64_t (thread_id)); - characters_written = ep_rt_utf8_string_snprintf (buffer, ARRAY_SIZE (buffer), "\"%lu\",\n]},", ep_rt_thread_id_t_to_uint64_t (thread_id)); + characters_written = ep_rt_utf8_string_snprintf (buffer, ARRAY_SIZE (buffer), "\"Thread (%" PRIu64 ")\"]},", ep_rt_thread_id_t_to_uint64_t (thread_id)); if (characters_written > 0 && characters_written < (int32_t)ARRAY_SIZE (buffer)) json_file_write_string (json_file, buffer); } From f2002f6ef3a9348a6635099d9129432f877a92fe Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Thu, 19 Jan 2023 10:05:41 -0800 Subject: [PATCH 17/32] fix non-windows build breaks and using paldebugbreak for TODOs --- .../Microsoft.NETCore.Native.Unix.targets | 2 +- .../nativeaot/Runtime/EmptyContainers.h | 10 +- .../nativeaot/Runtime/EmptyContainers2.h | 22 ++--- .../Runtime/disabledeventpipeinternal.cpp | 16 +-- .../nativeaot/Runtime/eventpipe/ds-rt-aot.h | 6 +- .../nativeaot/Runtime/eventpipe/ep-rt-aot.h | 98 +++++-------------- .../nativeaot/Runtime/eventpipeinternal.cpp | 12 +-- src/native/eventpipe/ep-json-file.c | 8 -- 8 files changed, 53 insertions(+), 121 deletions(-) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets index 10d69d803f46c..025a9b68ab0d1 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets @@ -43,7 +43,7 @@ The .NET Foundation licenses this file to you under the MIT license. $ORIGIN @executable_path - libeventpipe-disabled + libeventpipe-disabled libeventpipe-enabled diff --git a/src/coreclr/nativeaot/Runtime/EmptyContainers.h b/src/coreclr/nativeaot/Runtime/EmptyContainers.h index 9a044389fb00c..5da978100d724 100644 --- a/src/coreclr/nativeaot/Runtime/EmptyContainers.h +++ b/src/coreclr/nativeaot/Runtime/EmptyContainers.h @@ -142,7 +142,7 @@ class SList_EP void InsertHead(T *pObj) { - __debugbreak(); + PalDebugBreak(); } @@ -180,7 +180,7 @@ class SList_EP T * operator->() const { - __debugbreak(); + PalDebugBreak(); return m_cur; } @@ -231,13 +231,13 @@ struct SListElem_EP ElemT const & operator*() const { - __debugbreak(); + PalDebugBreak(); return m_Value; } ElemT & operator*() { - __debugbreak(); + PalDebugBreak(); return m_Value; } @@ -285,7 +285,7 @@ class CQuickArrayList_EP bool PushNoThrow(const T & value) { if(m_curSize >= maxSize) - __debugbreak(); + PalDebugBreak(); m_array[m_curSize++] = value; return true; } diff --git a/src/coreclr/nativeaot/Runtime/EmptyContainers2.h b/src/coreclr/nativeaot/Runtime/EmptyContainers2.h index eed1fb6916c52..9829c771e4103 100644 --- a/src/coreclr/nativeaot/Runtime/EmptyContainers2.h +++ b/src/coreclr/nativeaot/Runtime/EmptyContainers2.h @@ -36,7 +36,7 @@ class DefaultSHashTraits_EP static bool IsNull(const ELEMENT &e) { return e == (const ELEMENT) 0; } static bool IsDeleted(const ELEMENT &e) { - __debugbreak(); + PalDebugBreak(); return false; //return e == (const ELEMENT) -1; } @@ -316,12 +316,12 @@ class SHash_EP : public TRAITS bool AddNoThrow(const element_t &element) { - __debugbreak(); + PalDebugBreak(); return false; } bool AddOrReplaceNoThrow(const element_t &element) { - __debugbreak(); + PalDebugBreak(); return false; } @@ -332,13 +332,13 @@ class SHash_EP : public TRAITS void Remove(key_t key) { - __debugbreak(); + PalDebugBreak(); } // Remove the specific element. void Remove(Iterator& i) { - __debugbreak(); + PalDebugBreak(); } void RemoveAll() { @@ -508,17 +508,14 @@ class MapSHashTraits_EP : public DefaultSHashTraits_EP< KeyValuePair_EP(name), reinterpret_cast(value)) ? S_OK : HRESULT_FROM_WIN32(GetLastError()); - __debugbreak(); + PalDebugBreak(); return 0xffff; } @@ -309,7 +309,7 @@ ds_rt_server_log_pause_message (void) const char diagPortsName[] = "DOTNET_DiagnosticPorts"; // TODO: Cannot find nocache versions of RhConfig - __debugbreak(); + PalDebugBreak(); } #endif /* ENABLE_PERFTRACING */ diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h index 359bc2236c91d..77e30b2baa937 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h @@ -1148,7 +1148,7 @@ ep_rt_entrypoint_assembly_name_get_utf8 (void) STATIC_CONTRACT_NOTHROW; // TODO: Implement EventPipe assembly name - return filename in nativeaot? - __debugbreak(); + PalDebugBreak(); // fallback to the empty string if we can't get assembly info, e.g., if the runtime is // suspended before an assembly is loaded. @@ -1411,7 +1411,7 @@ ep_rt_method_get_simple_assembly_name ( STATIC_CONTRACT_NOTHROW; // TODO: Design MethodDesc and method name services if/when needed - __debugbreak(); + PalDebugBreak(); return false; @@ -1425,7 +1425,7 @@ ep_rt_method_get_full_name ( size_t name_len) { // TODO: Design MethodDesc and method name services if/when needed - __debugbreak(); + PalDebugBreak(); return false; } @@ -1436,26 +1436,6 @@ void ep_rt_provider_config_init (EventPipeProviderConfiguration *provider_config) { STATIC_CONTRACT_NOTHROW; - - // TODO: MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context is not available in NativeAOT - -/** - // Mono implementation - if (!ep_rt_utf8_string_compare (ep_config_get_rundown_provider_name_utf8 (), ep_provider_config_get_provider_name (provider_config))) { - MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_EVENTPIPE_Context.Level = (uint8_t)ep_provider_config_get_logging_level (provider_config); - MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_EVENTPIPE_Context.EnabledKeywordsBitmask = ep_provider_config_get_keywords (provider_config); - MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_EVENTPIPE_Context.IsEnabled = true; - } - - // CoreCLR - if (!ep_rt_utf8_string_compare (ep_config_get_rundown_provider_name_utf8 (), ep_provider_config_get_provider_name (provider_config))) { - MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context.EventPipeProvider.Level = (UCHAR) ep_provider_config_get_logging_level (provider_config); - MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context.EventPipeProvider.EnabledKeywordsBitmask = ep_provider_config_get_keywords (provider_config); - MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context.EventPipeProvider.IsEnabled = true; - } -*/ - - //__debugbreak(); } // This function is auto-generated from /src/scripts/genEventPipe.py @@ -1615,7 +1595,7 @@ ep_rt_config_value_get_config (void) STATIC_CONTRACT_NOTHROW; // TODO: EventPipe Configuration values - RhConfig? // (CLRConfig::INTERNAL_EventPipeConfig) - __debugbreak(); + PalDebugBreak(); return nullptr; // return ep_rt_utf16_to_utf8_string (reinterpret_cast(value.GetValue ()), -1); } @@ -1628,7 +1608,7 @@ ep_rt_config_value_get_output_path (void) STATIC_CONTRACT_NOTHROW; // TODO: EventPipe Configuration values - RhConfig? // (CLRConfig::INTERNAL_EventPipeOutputPath) - __debugbreak(); + PalDebugBreak(); return nullptr; } @@ -1640,7 +1620,7 @@ ep_rt_config_value_get_circular_mb (void) STATIC_CONTRACT_NOTHROW; // TODO: EventPipe Configuration values - RhConfig? // (CLRConfig::INTERNAL_EventPipeCircularMB) - __debugbreak(); + PalDebugBreak(); return 0; } @@ -1652,7 +1632,7 @@ ep_rt_config_value_get_output_streaming (void) STATIC_CONTRACT_NOTHROW; // TODO: EventPipe Configuration values - RhConfig? // (CLRConfig::INTERNAL_EventPipeOutputStreaming) - __debugbreak(); + PalDebugBreak(); return false; } @@ -1845,7 +1825,7 @@ ep_rt_wait_event_get_wait_handle (ep_rt_wait_event_handle_t *wait_event) EP_ASSERT (wait_event != NULL && wait_event->event != NULL); // TODO: NativeAOT CLREventStatic doesn't have GetHandleUNHOSTED - __debugbreak(); + PalDebugBreak(); return 0; } @@ -1881,8 +1861,6 @@ bool ep_rt_process_detach (void) { STATIC_CONTRACT_NOTHROW; - // TODO: Does NativeAot have the concept of process detach - // __debugbreak(); return false; } @@ -1893,8 +1871,6 @@ bool ep_rt_process_shutdown (void) { STATIC_CONTRACT_NOTHROW; - // TODO: Does NativeAot have the concept of process shutdown - //__debugbreak(); return false; } @@ -1948,7 +1924,7 @@ ep_rt_is_running (void) { STATIC_CONTRACT_NOTHROW; // TODO: Does NativeAot have the concept of EEStarted - __debugbreak(); + PalDebugBreak(); return false; } @@ -1963,7 +1939,7 @@ ep_rt_execute_rundown (ep_rt_execution_checkpoint_array_t *execution_checkpoints //TODO: Write execution checkpoint rundown events. // TODO: EventPipe Configuration values - RhConfig? // (CLRConfig::INTERNAL_EventPipeCircularMB) - __debugbreak(); + PalDebugBreak(); } /* @@ -2102,7 +2078,6 @@ ep_rt_set_server_name(void) { // TODO: Need to set name for the thread // ::SetThreadName(GetCurrentThread(), W(".NET EventPipe")); - //__debugbreak(); } @@ -2137,7 +2112,7 @@ ep_rt_current_processor_get_number (void) // PROCESSOR_NUMBER proc; // GetCurrentProcessorNumberEx (&proc); // return _ep_rt_aot_proc_group_offsets [proc.Group] + proc.Number; - __debugbreak(); + PalDebugBreak(); } #endif return 0xFFFFFFFF; @@ -2154,7 +2129,7 @@ ep_rt_processors_get_count (void) GetSystemInfo (&sys_info); return static_cast(sys_info.dwNumberOfProcessors); #else - __debugbreak(); + PalDebugBreak(); return 0xffff; #endif } @@ -2168,7 +2143,7 @@ ep_rt_current_thread_get_id (void) #ifdef TARGET_UNIX // TODO: AOT doesn't have PAL_GetCurrentOSThreadId, as CoreCLR does. - __debugbreak(); + PalDebugBreak(); return static_cast(0); #else return static_cast(::GetCurrentThreadId ()); @@ -2217,7 +2192,7 @@ ep_rt_system_time_get (EventPipeSystemTime *system_time) value.wMilliseconds); #else // TODO: Get System time - __debugbreak(); + PalDebugBreak(); #endif } @@ -2241,8 +2216,7 @@ ep_rt_system_get_alloc_granularity (void) { STATIC_CONTRACT_NOTHROW; // return static_cast(g_SystemInfo.dwAllocationGranularity); - //__debugbreak(); - return 0x10000;//0xffff; + return 0x10000; } static @@ -2266,7 +2240,7 @@ ep_rt_file_open_write (const ep_char8_t *path) ep_return_null_if_nok (path_utf16 != NULL); // TODO: Find out the way to open a file in native - __debugbreak(); + PalDebugBreak(); return 0; } @@ -2279,7 +2253,7 @@ ep_rt_file_close (ep_rt_file_handle_t file_handle) STATIC_CONTRACT_NOTHROW; // TODO: Find out the way to close a file in native - __debugbreak(); + PalDebugBreak(); return true; } @@ -2296,7 +2270,7 @@ ep_rt_file_write ( EP_ASSERT (buffer != NULL); // TODO: Find out the way to write to a file in native - __debugbreak(); + PalDebugBreak(); return false; } @@ -2355,7 +2329,7 @@ ep_rt_os_environment_get_utf16 (ep_rt_env_array_utf16_t *env_array) // } // FreeEnvironmentStringsW (envs); // } - __debugbreak(); + PalDebugBreak(); } /* @@ -2766,33 +2740,8 @@ ep_rt_diagnostics_command_line_get (void) // TODO: revisit commandline for AOT // return reinterpret_cast(::GetCommandLineA()); - - // In coreclr, this value can change over time, specifically before vs after suspension in diagnostics server. - // The host initializes the runtime in two phases, init and exec assembly. On non-Windows platforms the commandline returned by the runtime - // is different during each phase. We suspend during init where the runtime has populated the commandline with a - // mock value (the full path of the executing assembly) and the actual value isn't populated till the exec assembly phase. - // On Windows this does not apply as the value is retrieved directly from the OS any time it is requested. - // As a result, we cannot actually cache this value. We need to return the _current_ value. - // This function needs to handle freeing the string in order to make it consistent with Mono's version. - // There is a rare chance this may be called on multiple threads, so we attempt to always return the newest value - // and conservatively leak the old value if it changed. This is extremely rare and should only leak 1 string. extern ep_char8_t *volatile _ep_rt_aot_diagnostics_cmd_line; - ep_char8_t *old_cmd_line = _ep_rt_aot_diagnostics_cmd_line; - - // ep_char8_t *new_cmd_line = ep_rt_utf16_to_utf8_string (reinterpret_cast(GetCommandLineForDiagnostics ()), -1); - // __debugbreak(); - // ep_char8_t *new_cmd_line = NULL; - // if (old_cmd_line && ep_rt_utf8_string_compare (old_cmd_line, new_cmd_line) == 0) { - // // same as old, so free the new one - // ep_rt_utf8_string_free (new_cmd_line); - // } else { - // // attempt an update, and give up if you lose the race - // if (ep_rt_atomic_compare_exchange_utf8_string (&_ep_rt_aot_diagnostics_cmd_line, old_cmd_line, new_cmd_line) != old_cmd_line) { - // ep_rt_utf8_string_free (new_cmd_line); - // } - // } - return _ep_rt_aot_diagnostics_cmd_line; } @@ -2873,7 +2822,6 @@ ep_rt_thread_setup (void) // TODO: Implement thread creation/management if needed // Thread* thread_handle = SetupThreadNoThrow (); // EP_ASSERT (thread_handle != NULL); - //__debugbreak(); } static @@ -2922,7 +2870,7 @@ ep_rt_thread_get_id (ep_rt_thread_handle_t thread_handle) // TODO: Implement thread creation/management if needed // return ep_rt_uint64_t_to_thread_id_t (thread_handle->GetOSThreadId64 ()); - __debugbreak(); + PalDebugBreak(); return NULL; } @@ -2961,7 +2909,7 @@ ep_rt_thread_get_activity_id_handle (void) STATIC_CONTRACT_NOTHROW; // TODO: Implement thread creation/management if needed // return GetThread (); - __debugbreak(); + PalDebugBreak(); return NULL; } @@ -2975,7 +2923,7 @@ ep_rt_thread_get_activity_id_cref (ep_rt_thread_activity_id_handle_t activity_id // TODO: Implement thread creation/management if needed // return reinterpret_cast(activity_id_handle->GetActivityId ()); - __debugbreak(); + PalDebugBreak(); return NULL; } @@ -3010,7 +2958,7 @@ ep_rt_thread_set_activity_id ( // TODO: Implement thread creation/management if needed // activity_id_handle->SetActivityId (reinterpret_cast(activity_id)); - __debugbreak(); + PalDebugBreak(); } #undef EP_YIELD_WHILE diff --git a/src/coreclr/nativeaot/Runtime/eventpipeinternal.cpp b/src/coreclr/nativeaot/Runtime/eventpipeinternal.cpp index 06f16fc9c5c64..41461fd7f47b3 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipeinternal.cpp +++ b/src/coreclr/nativeaot/Runtime/eventpipeinternal.cpp @@ -32,7 +32,7 @@ EXTERN_C NATIVEAOT_API uint64_t __cdecl RhEventPipeInternal_Enable( /* COR_PRF_EVENTPIPE_PROVIDER_CONFIG */ const void * pProviders, uint32_t numProviders) { - __debugbreak(); + PalDebugBreak(); return 0; } @@ -86,7 +86,7 @@ EXTERN_C NATIVEAOT_API void __cdecl RhEventPipeInternal_DeleteProvider(intptr_t EXTERN_C NATIVEAOT_API int __cdecl RhEventPipeInternal_EventActivityIdControl(uint32_t controlCode, GUID *pActivityId) { - __debugbreak(); + PalDebugBreak(); return 0; } @@ -104,25 +104,25 @@ EXTERN_C NATIVEAOT_API void __cdecl RhEventPipeInternal_WriteEventData( EXTERN_C NATIVEAOT_API UInt32_BOOL __cdecl RhEventPipeInternal_GetSessionInfo(uint64_t sessionID, EventPipeSessionInfo *pSessionInfo) { - __debugbreak(); + PalDebugBreak(); return FALSE; } EXTERN_C NATIVEAOT_API UInt32_BOOL __cdecl RhEventPipeInternal_GetNextEvent(uint64_t sessionID, EventPipeEventInstanceData *pInstance) { - __debugbreak(); + PalDebugBreak(); return FALSE; } EXTERN_C NATIVEAOT_API UInt32_BOOL __cdecl RhEventPipeInternal_SignalSession(uint64_t sessionID) { - __debugbreak(); + PalDebugBreak(); return FALSE; } EXTERN_C NATIVEAOT_API UInt32_BOOL __cdecl RhEventPipeInternal_WaitForSessionSignal(uint64_t sessionID, int32_t timeoutMs) { - __debugbreak(); + PalDebugBreak(); return FALSE; } diff --git a/src/native/eventpipe/ep-json-file.c b/src/native/eventpipe/ep-json-file.c index 4f4ad65c1a0a5..8fe078e5c646a 100644 --- a/src/native/eventpipe/ep-json-file.c +++ b/src/native/eventpipe/ep-json-file.c @@ -9,15 +9,7 @@ #include "ep-event-instance.h" #include "ep-rt.h" -#ifdef HAVE_INTTYPES_H #include -#else -#if defined(TARGET_UNIX) -#define PRIu64 "lu" -#else -#define PRIu64 "llu" -#endif -#endif #ifdef EP_CHECKED_BUILD From 5b3037e33ef31862c4596529f78cbcfc448e69cd Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Thu, 19 Jan 2023 11:13:40 -0800 Subject: [PATCH 18/32] trying another option to get arounf inttypes.h and PRIu64 --- src/native/eventpipe/ep-json-file.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/native/eventpipe/ep-json-file.c b/src/native/eventpipe/ep-json-file.c index 8fe078e5c646a..8263896f0e844 100644 --- a/src/native/eventpipe/ep-json-file.c +++ b/src/native/eventpipe/ep-json-file.c @@ -9,7 +9,15 @@ #include "ep-event-instance.h" #include "ep-rt.h" -#include +// Some configurations don't seem to have access to inttypes.h +#ifndef PRIu64 +#if defined(TARGET_UNIX) +#define PRIu64 "lu" +#else +#define PRIu64 "llu" +#endif +#endif + #ifdef EP_CHECKED_BUILD From 602f27b8a2e36ce9e8d812596c2cf557d59d81bf Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Fri, 20 Jan 2023 15:00:35 -0800 Subject: [PATCH 19/32] reverting the changes in ep-json file in common code --- src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt | 1 + src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp | 2 +- src/native/eventpipe/ep-json-file.c | 8 +++----- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt index be658ca8782df..64dd6056a089a 100644 --- a/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt @@ -73,6 +73,7 @@ if(CLR_CMAKE_HOST_UNIX) if (CMAKE_VERSION VERSION_GREATER 3.11 OR CMAKE_VERSION VERSION_EQUAL 3.11) set_source_files_properties(${SHARED_EVENTPIPE_SOURCES} PROPERTIES COMPILE_OPTIONS -xc++) set_source_files_properties(${SHARED_DIAGNOSTIC_SERVER_SOURCES} PROPERTIES COMPILE_OPTIONS -xc++) + add_definitions(-DHAVE_INTTYPES_H) endif() endif(CLR_CMAKE_HOST_UNIX) diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp index a40deb050314c..389fef29a8d1b 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp @@ -34,7 +34,7 @@ ep_rt_aot_walk_managed_stack_for_thread ( ep_rt_thread_handle_t thread, EventPipeStackContents *stack_contents) { - __debugbreak(); + PalDebugBreak(); return false; } diff --git a/src/native/eventpipe/ep-json-file.c b/src/native/eventpipe/ep-json-file.c index 8263896f0e844..52e5011e3d08a 100644 --- a/src/native/eventpipe/ep-json-file.c +++ b/src/native/eventpipe/ep-json-file.c @@ -9,16 +9,14 @@ #include "ep-event-instance.h" #include "ep-rt.h" -// Some configurations don't seem to have access to inttypes.h +#ifdef HAVE_INTTYPES_H +#include +#else #ifndef PRIu64 -#if defined(TARGET_UNIX) -#define PRIu64 "lu" -#else #define PRIu64 "llu" #endif #endif - #ifdef EP_CHECKED_BUILD #define MAX_ASSEMBLY_NAME_LEN 256 From d8b5b9899b3c25ed3d0821257ff7cbb2baa9f473 Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Sun, 22 Jan 2023 08:31:22 -0800 Subject: [PATCH 20/32] Add an NativeAOT EventSource test --- .../tools/aot/ILCompiler/repro/Program.cs | 52 ++--------- .../tools/aot/ILCompiler/repro/repro.csproj | 7 +- .../reproNative/reproNative.vcxproj | 4 +- .../DiagnosticSourceEventSourceTests.cs | 3 + .../EventPipe.NativeAotTests.NYI | 14 +++ .../NativeAotTests/EventPipeClient/client.cs | 92 +++++++++++++++++++ .../NativeAotTarget/SimpleEventSourceTest.cs | 40 ++++++++ ...em.Diagnostics.Tracing.NativeAotTests.proj | 10 ++ 8 files changed, 170 insertions(+), 52 deletions(-) create mode 100644 src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/EventPipeClient/EventPipe.NativeAotTests.NYI create mode 100644 src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/EventPipeClient/client.cs create mode 100644 src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/NativeAotTarget/SimpleEventSourceTest.cs create mode 100644 src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/NativeAotTarget/System.Diagnostics.Tracing.NativeAotTests.proj diff --git a/src/coreclr/tools/aot/ILCompiler/repro/Program.cs b/src/coreclr/tools/aot/ILCompiler/repro/Program.cs index e3aed34c2f487..c18161fc3f445 100644 --- a/src/coreclr/tools/aot/ILCompiler/repro/Program.cs +++ b/src/coreclr/tools/aot/ILCompiler/repro/Program.cs @@ -1,52 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -namespace EP_Target -{ - using System; - using System.Diagnostics.Tracing; - using System.Threading; - - public static class Program - { - public static void Main(string[] args) - { - Console.WriteLine("Waiting 10 seconds to client to get the PID"); - Thread.Sleep(10 * 1000); - - TargetStartLogging(); - - Console.WriteLine("Done done!"); - } - - private static void TargetStartLogging() - { - DemoEventSource.Log.AppStarted("Hello World From .NET!", 12); - } - } +using System; - [EventSource(Name = "Demo")] - class DemoEventSource : EventSource +class Program +{ + static void Main() { - public static DemoEventSource Log { get; } = new DemoEventSource(); - - [Event(1, Keywords = Keywords.Startup)] - public void AppStarted(string message, int favoriteNumber) => WriteEvent(1, message, favoriteNumber); - - [Event(2, Keywords = Keywords.Requests)] - public void RequestStart(int requestId) => WriteEvent(2, requestId); - - [Event(3, Keywords = Keywords.Requests)] - public void RequestStop(int requestId) => WriteEvent(3, requestId); - - [Event(4, Keywords = Keywords.Startup, Level = EventLevel.Verbose)] - public void DebugMessage(string message) => WriteEvent(4, message); - - - public class Keywords - { - public const EventKeywords Startup = (EventKeywords)0x0001; - public const EventKeywords Requests = (EventKeywords)0x0002; - } + Console.WriteLine("Hello world"); } -} +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/ILCompiler/repro/repro.csproj b/src/coreclr/tools/aot/ILCompiler/repro/repro.csproj index 1787116202c08..88a3d0f3177ef 100644 --- a/src/coreclr/tools/aot/ILCompiler/repro/repro.csproj +++ b/src/coreclr/tools/aot/ILCompiler/repro/repro.csproj @@ -6,12 +6,11 @@ AnyCPU false false - linux-x64;win-x64;osx-x64 + linux-x64;win-x64;osx-x64;freebsd-x64 Debug;Release;Checked true false false - true - + @@ -47,4 +46,4 @@ Overwrite="true" WriteOnlyWhenDifferent="true" /> - + \ No newline at end of file diff --git a/src/coreclr/tools/aot/ILCompiler/reproNative/reproNative.vcxproj b/src/coreclr/tools/aot/ILCompiler/reproNative/reproNative.vcxproj index f2f9dcb9935f3..5ac6a0332fc04 100644 --- a/src/coreclr/tools/aot/ILCompiler/reproNative/reproNative.vcxproj +++ b/src/coreclr/tools/aot/ILCompiler/reproNative/reproNative.vcxproj @@ -81,7 +81,7 @@ Console true - $(ArtifactsRoot)bin\repro\x64\Debug\repro.obj;$(Win32SDKLibs);%(AdditionalDependencies);$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\Runtime.WorkstationGC.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\System.Globalization.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\System.IO.Compression.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\eventPipe-enabled.lib; + $(ArtifactsRoot)bin\repro\x64\Debug\repro.obj;$(Win32SDKLibs);%(AdditionalDependencies);$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\Runtime.WorkstationGC.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\System.Globalization.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\System.IO.Compression.Native.Aot.lib @@ -134,4 +134,4 @@ - + \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/DiagnosticSourceEventSourceTests.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/DiagnosticSourceEventSourceTests.cs index 50582fdaf398b..832dfe72cb5d4 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/DiagnosticSourceEventSourceTests.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/DiagnosticSourceEventSourceTests.cs @@ -44,6 +44,9 @@ protected override void OnEventWritten(EventWrittenEventArgs eventData) public static int Main() { + // Remove this check after fixing https://github.com/dotnet/runtime/issues/80999 + if(!OperatingSystem.IsWindows()) + return 100; DiagnosticSource diagnosticSource = new DiagnosticListener("TestDiagnosticListener"); using (var listener = new TestEventListener()) { diff --git a/src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/EventPipeClient/EventPipe.NativeAotTests.NYI b/src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/EventPipeClient/EventPipe.NativeAotTests.NYI new file mode 100644 index 0000000000000..8d4f5453dda4d --- /dev/null +++ b/src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/EventPipeClient/EventPipe.NativeAotTests.NYI @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/EventPipeClient/client.cs b/src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/EventPipeClient/client.cs new file mode 100644 index 0000000000000..4680d036c0d75 --- /dev/null +++ b/src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/EventPipeClient/client.cs @@ -0,0 +1,92 @@ +using System.Diagnostics; +using System.Diagnostics.Tracing; +using System.Linq; + +using Microsoft.Diagnostics.NETCore.Client; +using Microsoft.Diagnostics.Tracing.Parsers; +using Microsoft.Diagnostics.Tracing; + +namespace EP_Client; + +public class Program +{ + public static int Main(string[] args) + { + // Remove this check after fixing https://github.com/dotnet/runtime/issues/80999 + if(!OperatingSystem.IsWindows()) + return 100; + + string processName = "reproNative"; + if (args.Length > 0) + { + processName = args[0]; + } + var intPid = Process.GetProcessesByName(processName).Single().Id; + + Console.WriteLine($"Starting an StartEventPipeSession for Process:<{processName}>, PID:{intPid}"); + + return PrintEventsLive(intPid); + } + + public static int PrintEventsLive(int processId) + { + int retCode = -1; + bool managedEvent = false, nativeEvent = false; + var providers = new List() + { + new EventPipeProvider("Demo", + EventLevel.Verbose, (long)ClrTraceEventParser.Keywords.Default) + }; + var client = new DiagnosticsClient(processId); + using (var session = client.StartEventPipeSession(providers, false)) + { + + Task streamTask = Task.Run(() => + { + var source = new EventPipeEventSource(session.EventStream); + source.Dynamic.All += (TraceEvent data) => + { + + if(data.ProviderName=="Demo" && + data.EventName == "AppStarted" && + data.PayloadNames.Length == 2 && + (string)data.PayloadByName(data.PayloadNames[0])=="Data from NativeAOT app!" && + (int)data.PayloadByName(data.PayloadNames[1])==42) + { + managedEvent=true; + } + if (data.ProviderName=="Microsoft-DotNETCore-EventPipe" && data.EventName == "ProcessInfo") + { + nativeEvent = true; + } + }; + + try + { + source.Process(); + } + catch (Exception e) + { + retCode = 1; + Console.WriteLine("Error encountered while processing events"); + Console.WriteLine(e.ToString()); + } + }); + + Task inputTask = Task.Run(() => + { + Console.WriteLine("Press Enter to exit"); + while (Console.ReadKey().Key != ConsoleKey.Enter) + { + Thread.Sleep(100); + } + session.Stop(); + }); + + Task.WaitAny(streamTask, inputTask); + } + if (managedEvent && nativeEvent) + retCode = 100; + return retCode; + } +} diff --git a/src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/NativeAotTarget/SimpleEventSourceTest.cs b/src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/NativeAotTarget/SimpleEventSourceTest.cs new file mode 100644 index 0000000000000..1ec3692f9be54 --- /dev/null +++ b/src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/NativeAotTarget/SimpleEventSourceTest.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace EP_Target +{ + using System; + using System.Diagnostics.Tracing; + using System.Threading; + + public static class Program + { + public static int Main(string[] args) + { + // Waiting 10 seconds to client to get the PID + Thread.Sleep(10 * 1000); + TargetStartLogging(); + // returning success since the actual test is in ..\EventPipeClient + return 100; + } + + private static void TargetStartLogging() + { + DemoEventSource.Log.AppStarted("Data from NativeAOT app!", 42); + } + } + + [EventSource(Name = "Demo")] + class DemoEventSource : EventSource + { + public static DemoEventSource Log { get; } = new DemoEventSource(); + + [Event(1, Keywords = Keywords.Startup)] + public void AppStarted(string message, int favoriteNumber) => WriteEvent(1, message, favoriteNumber); + + public class Keywords + { + public const EventKeywords Startup = (EventKeywords)0x0001; + } + } +} diff --git a/src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/NativeAotTarget/System.Diagnostics.Tracing.NativeAotTests.proj b/src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/NativeAotTarget/System.Diagnostics.Tracing.NativeAotTests.proj new file mode 100644 index 0000000000000..eff49fd42b247 --- /dev/null +++ b/src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/NativeAotTarget/System.Diagnostics.Tracing.NativeAotTests.proj @@ -0,0 +1,10 @@ + + + + + + + + + From 93b0e9df1dbac02996b82ef51eced2a9744ef46d Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Mon, 23 Jan 2023 17:34:52 -0800 Subject: [PATCH 21/32] FB and only enabling FEATURE_PERFTRACING in Windows --- .../Microsoft.NETCore.Native.Unix.targets | 6 +- .../Microsoft.NETCore.Native.Windows.targets | 6 +- src/coreclr/nativeaot/Directory.Build.props | 13 ++- .../nativeaot/Runtime/EmptyContainers.h | 5 +- .../Runtime/disabledeventpipeinternal.cpp | 21 +---- .../nativeaot/Runtime/eventpipe/ep-rt-aot.h | 2 +- .../tools/aot/ILCompiler/repro/Program.cs | 2 +- .../tools/aot/ILCompiler/repro/repro.csproj | 2 +- .../reproNative/reproNative.vcxproj | 2 +- .../DiagnosticSourceEventSourceTests.cs | 3 - .../EventPipe.NativeAotTests.NYI | 14 --- .../NativeAotTests/EventPipeClient/client.cs | 92 ------------------- .../NativeAotTarget/SimpleEventSourceTest.cs | 40 -------- ...em.Diagnostics.Tracing.NativeAotTests.proj | 10 -- 14 files changed, 23 insertions(+), 195 deletions(-) delete mode 100644 src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/EventPipeClient/EventPipe.NativeAotTests.NYI delete mode 100644 src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/EventPipeClient/client.cs delete mode 100644 src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/NativeAotTarget/SimpleEventSourceTest.cs delete mode 100644 src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/NativeAotTarget/System.Diagnostics.Tracing.NativeAotTests.proj diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets index 025a9b68ab0d1..312c891928882 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets @@ -43,8 +43,8 @@ The .NET Foundation licenses this file to you under the MIT license. $ORIGIN @executable_path - libeventpipe-disabled - libeventpipe-enabled + libeventpipe-disabled + libeventpipe-enabled @@ -52,7 +52,7 @@ The .NET Foundation licenses this file to you under the MIT license. - + diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets index d8fffa5e642bd..735732dcd5126 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets @@ -25,8 +25,8 @@ The .NET Foundation licenses this file to you under the MIT license. wmainCRTStartup WINDOWS CONSOLE - eventpipe-disabled - eventpipe-enabled + eventpipe-disabled + eventpipe-enabled @@ -35,7 +35,7 @@ The .NET Foundation licenses this file to you under the MIT license. - + diff --git a/src/coreclr/nativeaot/Directory.Build.props b/src/coreclr/nativeaot/Directory.Build.props index 8bed9ddc84653..ed31fad36b314 100644 --- a/src/coreclr/nativeaot/Directory.Build.props +++ b/src/coreclr/nativeaot/Directory.Build.props @@ -4,10 +4,6 @@ false - - - true - false @@ -43,7 +39,6 @@ NATIVEAOT;NETCOREAPP - $(DefineConstants);FEATURE_PERFTRACING true @@ -71,6 +66,14 @@ FEATURE_OBJCMARSHAL;$(DefineConstants) + + false + true + + + FEATURE_PERFTRACING;$(DefineConstants) + + diff --git a/src/coreclr/nativeaot/Runtime/EmptyContainers.h b/src/coreclr/nativeaot/Runtime/EmptyContainers.h index 5da978100d724..5662eadd03015 100644 --- a/src/coreclr/nativeaot/Runtime/EmptyContainers.h +++ b/src/coreclr/nativeaot/Runtime/EmptyContainers.h @@ -247,10 +247,9 @@ struct SListElem_EP { } - template - SListElem_EP(T1&& val) + SListElem_EP(ElemT val) : m_Link() - , m_Value(std::forward(val)) + , m_Value(val) { } diff --git a/src/coreclr/nativeaot/Runtime/disabledeventpipeinternal.cpp b/src/coreclr/nativeaot/Runtime/disabledeventpipeinternal.cpp index c5b666c665ff8..2c4ac486ec83a 100644 --- a/src/coreclr/nativeaot/Runtime/disabledeventpipeinternal.cpp +++ b/src/coreclr/nativeaot/Runtime/disabledeventpipeinternal.cpp @@ -6,24 +6,9 @@ #ifdef FEATURE_PERFTRACING -struct EventPipeEventInstanceData -{ - void *ProviderID; - unsigned int EventID; - unsigned int ThreadID; - LARGE_INTEGER TimeStamp; - GUID ActivityId; - GUID RelatedActivityId; - const uint8_t *Payload; - unsigned int PayloadLength; -}; - -struct EventPipeSessionInfo -{ - FILETIME StartTimeAsUTCFileTime; - LARGE_INTEGER StartTimeStamp; - LARGE_INTEGER TimeStampFrequency; -}; +struct EventPipeEventInstanceData; + +struct EventPipeSessionInfo; EXTERN_C NATIVEAOT_API uint64_t __cdecl RhEventPipeInternal_Enable( LPCWSTR outputFile, diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h index 77e30b2baa937..4ee8341661a36 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h @@ -2871,7 +2871,7 @@ ep_rt_thread_get_id (ep_rt_thread_handle_t thread_handle) // TODO: Implement thread creation/management if needed // return ep_rt_uint64_t_to_thread_id_t (thread_handle->GetOSThreadId64 ()); PalDebugBreak(); - return NULL; + return 0; } static diff --git a/src/coreclr/tools/aot/ILCompiler/repro/Program.cs b/src/coreclr/tools/aot/ILCompiler/repro/Program.cs index c18161fc3f445..9e71394c3732a 100644 --- a/src/coreclr/tools/aot/ILCompiler/repro/Program.cs +++ b/src/coreclr/tools/aot/ILCompiler/repro/Program.cs @@ -9,4 +9,4 @@ static void Main() { Console.WriteLine("Hello world"); } -} \ No newline at end of file +} diff --git a/src/coreclr/tools/aot/ILCompiler/repro/repro.csproj b/src/coreclr/tools/aot/ILCompiler/repro/repro.csproj index 88a3d0f3177ef..f2d7f5c109a05 100644 --- a/src/coreclr/tools/aot/ILCompiler/repro/repro.csproj +++ b/src/coreclr/tools/aot/ILCompiler/repro/repro.csproj @@ -46,4 +46,4 @@ Overwrite="true" WriteOnlyWhenDifferent="true" /> - \ No newline at end of file + diff --git a/src/coreclr/tools/aot/ILCompiler/reproNative/reproNative.vcxproj b/src/coreclr/tools/aot/ILCompiler/reproNative/reproNative.vcxproj index 5ac6a0332fc04..ee8d32964d805 100644 --- a/src/coreclr/tools/aot/ILCompiler/reproNative/reproNative.vcxproj +++ b/src/coreclr/tools/aot/ILCompiler/reproNative/reproNative.vcxproj @@ -134,4 +134,4 @@ - \ No newline at end of file + diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/DiagnosticSourceEventSourceTests.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/DiagnosticSourceEventSourceTests.cs index 832dfe72cb5d4..50582fdaf398b 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/DiagnosticSourceEventSourceTests.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/DiagnosticSourceEventSourceTests.cs @@ -44,9 +44,6 @@ protected override void OnEventWritten(EventWrittenEventArgs eventData) public static int Main() { - // Remove this check after fixing https://github.com/dotnet/runtime/issues/80999 - if(!OperatingSystem.IsWindows()) - return 100; DiagnosticSource diagnosticSource = new DiagnosticListener("TestDiagnosticListener"); using (var listener = new TestEventListener()) { diff --git a/src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/EventPipeClient/EventPipe.NativeAotTests.NYI b/src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/EventPipeClient/EventPipe.NativeAotTests.NYI deleted file mode 100644 index 8d4f5453dda4d..0000000000000 --- a/src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/EventPipeClient/EventPipe.NativeAotTests.NYI +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/EventPipeClient/client.cs b/src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/EventPipeClient/client.cs deleted file mode 100644 index 4680d036c0d75..0000000000000 --- a/src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/EventPipeClient/client.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System.Diagnostics; -using System.Diagnostics.Tracing; -using System.Linq; - -using Microsoft.Diagnostics.NETCore.Client; -using Microsoft.Diagnostics.Tracing.Parsers; -using Microsoft.Diagnostics.Tracing; - -namespace EP_Client; - -public class Program -{ - public static int Main(string[] args) - { - // Remove this check after fixing https://github.com/dotnet/runtime/issues/80999 - if(!OperatingSystem.IsWindows()) - return 100; - - string processName = "reproNative"; - if (args.Length > 0) - { - processName = args[0]; - } - var intPid = Process.GetProcessesByName(processName).Single().Id; - - Console.WriteLine($"Starting an StartEventPipeSession for Process:<{processName}>, PID:{intPid}"); - - return PrintEventsLive(intPid); - } - - public static int PrintEventsLive(int processId) - { - int retCode = -1; - bool managedEvent = false, nativeEvent = false; - var providers = new List() - { - new EventPipeProvider("Demo", - EventLevel.Verbose, (long)ClrTraceEventParser.Keywords.Default) - }; - var client = new DiagnosticsClient(processId); - using (var session = client.StartEventPipeSession(providers, false)) - { - - Task streamTask = Task.Run(() => - { - var source = new EventPipeEventSource(session.EventStream); - source.Dynamic.All += (TraceEvent data) => - { - - if(data.ProviderName=="Demo" && - data.EventName == "AppStarted" && - data.PayloadNames.Length == 2 && - (string)data.PayloadByName(data.PayloadNames[0])=="Data from NativeAOT app!" && - (int)data.PayloadByName(data.PayloadNames[1])==42) - { - managedEvent=true; - } - if (data.ProviderName=="Microsoft-DotNETCore-EventPipe" && data.EventName == "ProcessInfo") - { - nativeEvent = true; - } - }; - - try - { - source.Process(); - } - catch (Exception e) - { - retCode = 1; - Console.WriteLine("Error encountered while processing events"); - Console.WriteLine(e.ToString()); - } - }); - - Task inputTask = Task.Run(() => - { - Console.WriteLine("Press Enter to exit"); - while (Console.ReadKey().Key != ConsoleKey.Enter) - { - Thread.Sleep(100); - } - session.Stop(); - }); - - Task.WaitAny(streamTask, inputTask); - } - if (managedEvent && nativeEvent) - retCode = 100; - return retCode; - } -} diff --git a/src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/NativeAotTarget/SimpleEventSourceTest.cs b/src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/NativeAotTarget/SimpleEventSourceTest.cs deleted file mode 100644 index 1ec3692f9be54..0000000000000 --- a/src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/NativeAotTarget/SimpleEventSourceTest.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace EP_Target -{ - using System; - using System.Diagnostics.Tracing; - using System.Threading; - - public static class Program - { - public static int Main(string[] args) - { - // Waiting 10 seconds to client to get the PID - Thread.Sleep(10 * 1000); - TargetStartLogging(); - // returning success since the actual test is in ..\EventPipeClient - return 100; - } - - private static void TargetStartLogging() - { - DemoEventSource.Log.AppStarted("Data from NativeAOT app!", 42); - } - } - - [EventSource(Name = "Demo")] - class DemoEventSource : EventSource - { - public static DemoEventSource Log { get; } = new DemoEventSource(); - - [Event(1, Keywords = Keywords.Startup)] - public void AppStarted(string message, int favoriteNumber) => WriteEvent(1, message, favoriteNumber); - - public class Keywords - { - public const EventKeywords Startup = (EventKeywords)0x0001; - } - } -} diff --git a/src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/NativeAotTarget/System.Diagnostics.Tracing.NativeAotTests.proj b/src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/NativeAotTarget/System.Diagnostics.Tracing.NativeAotTests.proj deleted file mode 100644 index eff49fd42b247..0000000000000 --- a/src/libraries/System.Diagnostics.Tracing/tests/NativeAotTests/NativeAotTarget/System.Diagnostics.Tracing.NativeAotTests.proj +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - From 31535feb85273e987073206679135b18d311c2ee Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Wed, 25 Jan 2023 18:23:57 -0800 Subject: [PATCH 22/32] fix DiagnosticEventSource test --- src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt | 1 - .../nativeaot/Runtime/eventpipe/ep-rt-types-aot.h | 2 ++ ...stem.Diagnostics.DiagnosticSource.NativeAotTests.proj | 9 +++++++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt index 64dd6056a089a..be658ca8782df 100644 --- a/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt @@ -73,7 +73,6 @@ if(CLR_CMAKE_HOST_UNIX) if (CMAKE_VERSION VERSION_GREATER 3.11 OR CMAKE_VERSION VERSION_EQUAL 3.11) set_source_files_properties(${SHARED_EVENTPIPE_SOURCES} PROPERTIES COMPILE_OPTIONS -xc++) set_source_files_properties(${SHARED_DIAGNOSTIC_SERVER_SOURCES} PROPERTIES COMPILE_OPTIONS -xc++) - add_definitions(-DHAVE_INTTYPES_H) endif() endif(CLR_CMAKE_HOST_UNIX) diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h index 8e395237f91c1..ce5a0cb7fb9e5 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h @@ -4,6 +4,8 @@ #include +#include + #ifdef ENABLE_PERFTRACING #include "gcenv.h" diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/System.Diagnostics.DiagnosticSource.NativeAotTests.proj b/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/System.Diagnostics.DiagnosticSource.NativeAotTests.proj index ec8c46ce38663..411f12fb69124 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/System.Diagnostics.DiagnosticSource.NativeAotTests.proj +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/System.Diagnostics.DiagnosticSource.NativeAotTests.proj @@ -1,9 +1,14 @@ - + + + + + + EnabledProperties="EventSourceSupport" /> From cdf37d453620106e716df3b098c657c5772d42b7 Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Sun, 29 Jan 2023 11:32:15 -0800 Subject: [PATCH 23/32] FB --- src/coreclr/nativeaot/Runtime/CMakeLists.txt | 59 +-- .../nativeaot/Runtime/EmptyContainers.h | 1 + .../nativeaot/Runtime/EmptyContainers2.h | 1 + .../nativeaot/Runtime/Full/CMakeLists.txt | 3 +- .../nativeaot/Runtime/eventpipe/ds-rt-aot.h | 9 +- .../nativeaot/Runtime/eventpipe/ep-rt-aot.h | 100 ++-- .../nativeaot/Runtime/eventpipeadapter.h | 441 ------------------ .../Diagnostics/Tracing/RuntimeEventSource.cs | 2 +- .../src/System/Threading/Overlapped.cs | 2 +- src/native/eventpipe/ds-ipc-pal-namedpipe.h | 3 - .../tracing/eventpipe/common/IpcTraceTest.cs | 4 + .../providervalidation/providervalidation.cs | 10 + .../providervalidation.csproj | 2 + 13 files changed, 76 insertions(+), 561 deletions(-) diff --git a/src/coreclr/nativeaot/Runtime/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/CMakeLists.txt index bbdd424ce8062..d3c7e55188646 100644 --- a/src/coreclr/nativeaot/Runtime/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/CMakeLists.txt @@ -11,67 +11,12 @@ include_directories(${SHARED_EVENTPIPE_SOURCE_DIR}) set (AOT_EVENTPIPE_SHIM_SOURCES "") set (AOT_EVENTPIPE_SHIM_HEADERS "") set (AOT_EVENTPIPE_MANAGED_TO_NATIVE_SOURCES "") -set (SHARED_EVENTPIPE_SOURCES "") -set (SHARED_EVENTPIPE_HEADERS "") set (SHARED_DIAGNOSTIC_SERVER_SOURCES "") set (SHARED_DIAGNOSTIC_SERVER_HEADERS "") set (AOT_EVENTPIPE_DISABLED_SOURCES "") -list(APPEND SHARED_EVENTPIPE_SOURCES - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-sources.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-block.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-buffer.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-buffer-manager.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-config.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event-instance.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event-payload.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event-source.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-file.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-json-file.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-metadata-generator.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-provider.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-sample-profiler.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-session.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-session-provider.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-stack-contents.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-stream.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-thread.c -) - -list(APPEND SHARED_EVENTPIPE_HEADERS - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-block.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-buffer.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-buffer-manager.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-config.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-config-internals.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event-instance.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event-payload.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event-source.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-file.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-getter-setter.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-ipc-pal-types.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-ipc-pal-types-forward.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-ipc-stream.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-json-file.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-metadata-generator.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-provider.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-provider-internals.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-rt.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-rt-config.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-rt-types.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-sample-profiler.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-session.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-session-provider.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-stack-contents.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-stream.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-thread.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-types.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-types-forward.h -) +set (SHARED_EVENTPIPE_SOURCE_PATH "${CLR_SRC_NATIVE_DIR}/eventpipe") +include (${SHARED_EVENTPIPE_SOURCE_PATH}/CMakeLists.txt) list(APPEND SHARED_DIAGNOSTIC_SERVER_SOURCES ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-sources.c diff --git a/src/coreclr/nativeaot/Runtime/EmptyContainers.h b/src/coreclr/nativeaot/Runtime/EmptyContainers.h index 5662eadd03015..e317309c55bf7 100644 --- a/src/coreclr/nativeaot/Runtime/EmptyContainers.h +++ b/src/coreclr/nativeaot/Runtime/EmptyContainers.h @@ -5,6 +5,7 @@ #define __EmptyContainers_h__ // This header file will contains minimal containers that are needed for EventPipe library implementation +// shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // @TODO - this will likely be replaced by the common container classes to be added to the EventPipe library // Hence initially, the bare boned implementation focus is on unblocking HW/Simple Trace bring up diff --git a/src/coreclr/nativeaot/Runtime/EmptyContainers2.h b/src/coreclr/nativeaot/Runtime/EmptyContainers2.h index 9829c771e4103..f045afc4d36e6 100644 --- a/src/coreclr/nativeaot/Runtime/EmptyContainers2.h +++ b/src/coreclr/nativeaot/Runtime/EmptyContainers2.h @@ -5,6 +5,7 @@ #define __EmptyContainers2_h__ // This header file will contains minimal containers that are needed for EventPipe library implementation +// shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // @TODO - this will likely be replaced by the common container classes to be added to the EventPipe library // Hence initially, the bare boned implementation focus is on unblocking HW/Simple Trace bring up diff --git a/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt index be658ca8782df..2fdca83c79723 100644 --- a/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt @@ -7,6 +7,7 @@ project(Runtime) set(CMAKE_INCLUDE_CURRENT_DIR ON) add_definitions(-DFEATURE_RX_THUNKS) +add_definitions(-DFEATURE_PERFTRACING) if (CLR_CMAKE_TARGET_WIN32) if (CLR_CMAKE_HOST_ARCH_ARM OR CLR_CMAKE_HOST_ARCH_ARM64) @@ -76,8 +77,6 @@ if(CLR_CMAKE_HOST_UNIX) endif() endif(CLR_CMAKE_HOST_UNIX) -add_definitions(-DFEATURE_PERFTRACING) - if (WIN32) set_source_files_properties(${SHARED_EVENTPIPE_SOURCES} PROPERTIES COMPILE_FLAGS "/FI\"${RUNTIME_DIR}/eventpipe/NativeaotEventPipeSupport.h\"") set_source_files_properties(${SHARED_DIAGNOSTIC_SERVER_SOURCES} PROPERTIES COMPILE_FLAGS "/FI\"${RUNTIME_DIR}/eventpipe/NativeaotEventPipeSupport.h\"") diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ds-rt-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ds-rt-aot.h index c58c0a4871890..6f847d4f1c8b6 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ds-rt-aot.h +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ds-rt-aot.h @@ -140,6 +140,7 @@ ds_rt_config_value_get_enable (void) { STATIC_CONTRACT_NOTHROW; + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: EventPipe Configuration values - RhConfig? return true; } @@ -149,6 +150,7 @@ inline ep_char8_t * ds_rt_config_value_get_ports (void) { + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: EventPipe Configuration values - RhConfig? return nullptr; } @@ -159,6 +161,7 @@ uint32_t ds_rt_config_value_get_default_port_suspend (void) { STATIC_CONTRACT_NOTHROW; + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: EventPipe Configuration values - RhConfig? return 0; } @@ -179,6 +182,7 @@ ds_rt_generate_core_dump ( ds_ipc_result_t result = DS_IPC_E_FAIL; uint32_t flags = ds_generate_core_dump_command_payload_get_flags(payload); + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Generate an exception dump PalDebugBreak(); @@ -202,10 +206,8 @@ ds_rt_transport_get_default_name ( { STATIC_CONTRACT_NOTHROW; + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: PAL_GetTransportName is defined in coreclr\pal\inc\pal.h -// #ifdef TARGET_UNIX -// PAL_GetTransportName (name_len, name, prefix, id, group_id, suffix); -// #endif return true; } @@ -308,6 +310,7 @@ ds_rt_server_log_pause_message (void) STATIC_CONTRACT_NOTHROW; const char diagPortsName[] = "DOTNET_DiagnosticPorts"; + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Cannot find nocache versions of RhConfig PalDebugBreak(); } diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h index 4ee8341661a36..7831f0dc27e0e 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h @@ -24,7 +24,6 @@ #ifdef _INC_WINDOWS #include #endif -// @TODO - temp, lakshanf. This is not used in NativeAOT #define STATIC_CONTRACT_NOTHROW #undef EP_INFINITE_WAIT @@ -45,6 +44,7 @@ #undef EP_ALIGN_UP #define EP_ALIGN_UP(val,align) _rt_aot_align_up(val,align) +// shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: The NativeAOT ALIGN_UP is defined in a tangled manner that generates linker errors if // it is used here; instead, define a version tailored to the existing usage in the shared // EventPipe code. @@ -616,7 +616,6 @@ _rt_aot_hash_map_free (HASH_MAP_TYPE *hash_map) EP_ASSERT (HASH_MAP_TYPE::table_type_t::s_NoThrow); EP_ASSERT (hash_map != NULL); - // @TODO - LakshanF: 10/21/22 - Need to understand more on value_free_func, specifically how iterator->Value () gets called if (hash_map->table) { if (hash_map->callbacks.value_free_func) { for (typename HASH_MAP_TYPE::table_type_t::Iterator iterator = hash_map->table->Begin (); iterator != hash_map->table->End (); ++iterator) @@ -1136,6 +1135,7 @@ inline ep_rt_lock_handle_t * ep_rt_aot_config_lock_get (void) { + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implement EventPipe locking for NativeAOT return nullptr; } @@ -1147,6 +1147,7 @@ ep_rt_entrypoint_assembly_name_get_utf8 (void) { STATIC_CONTRACT_NOTHROW; + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implement EventPipe assembly name - return filename in nativeaot? PalDebugBreak(); @@ -1160,6 +1161,7 @@ const ep_char8_t * ep_rt_runtime_version_get_utf8 (void) { STATIC_CONTRACT_NOTHROW; + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Find a way to use CoreCLR runtime_version.h here if a more exact version is needed return reinterpret_cast("8.0.0"); } @@ -1271,6 +1273,7 @@ ep_rt_atomic_inc_int64_t (volatile int64_t *value) { STATIC_CONTRACT_NOTHROW; + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Consider replacing with a new PalInterlockedIncrement64 service int64_t currentValue; do { @@ -1287,6 +1290,7 @@ int64_t ep_rt_atomic_dec_int64_t (volatile int64_t *value) { STATIC_CONTRACT_NOTHROW; + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Consider replacing with a new PalInterlockedDecrement64 service int64_t currentValue; do { @@ -1331,6 +1335,7 @@ static void ep_rt_init (void) { + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implement EventPipe locking for NativeAOT } @@ -1355,6 +1360,7 @@ inline bool ep_rt_config_acquire (void) { + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implement EventPipe locking for NativeAOT return true; } @@ -1364,6 +1370,7 @@ inline bool ep_rt_config_release (void) { + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implement EventPipe locking for NativeAOT return true; } @@ -1374,6 +1381,7 @@ inline void ep_rt_config_requires_lock_held (void) { + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implement EventPipe locking for NativeAOT return; } @@ -1383,6 +1391,7 @@ inline void ep_rt_config_requires_lock_not_held (void) { + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implement EventPipe locking for NativeAOT return; } @@ -1410,6 +1419,7 @@ ep_rt_method_get_simple_assembly_name ( { STATIC_CONTRACT_NOTHROW; + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Design MethodDesc and method name services if/when needed PalDebugBreak(); @@ -1424,6 +1434,7 @@ ep_rt_method_get_full_name ( ep_char8_t *name, size_t name_len) { + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Design MethodDesc and method name services if/when needed PalDebugBreak(); @@ -1449,6 +1460,7 @@ static void ep_rt_init_providers_and_events (void) { + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: auto-generated fn, no op for now // InitProvidersAndEvents (); } @@ -1459,6 +1471,7 @@ bool ep_rt_providers_validate_all_disabled (void) { STATIC_CONTRACT_NOTHROW; + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context and MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_DOTNET_Context are not available in NativeAOT return true; } @@ -1580,6 +1593,7 @@ inline bool ep_rt_config_value_get_enable (void) { + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: EventPipe Configuration values - RhConfig? // (CLRConfig::INTERNAL_EnableEventPipe) != 0 // If EventPipe environment variables are specified, parse them and start a session. @@ -1593,6 +1607,7 @@ ep_char8_t * ep_rt_config_value_get_config (void) { STATIC_CONTRACT_NOTHROW; + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: EventPipe Configuration values - RhConfig? // (CLRConfig::INTERNAL_EventPipeConfig) PalDebugBreak(); @@ -1606,6 +1621,7 @@ ep_char8_t * ep_rt_config_value_get_output_path (void) { STATIC_CONTRACT_NOTHROW; + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: EventPipe Configuration values - RhConfig? // (CLRConfig::INTERNAL_EventPipeOutputPath) PalDebugBreak(); @@ -1618,6 +1634,7 @@ uint32_t ep_rt_config_value_get_circular_mb (void) { STATIC_CONTRACT_NOTHROW; + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: EventPipe Configuration values - RhConfig? // (CLRConfig::INTERNAL_EventPipeCircularMB) PalDebugBreak(); @@ -1630,6 +1647,7 @@ bool ep_rt_config_value_get_output_streaming (void) { STATIC_CONTRACT_NOTHROW; + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: EventPipe Configuration values - RhConfig? // (CLRConfig::INTERNAL_EventPipeOutputStreaming) PalDebugBreak(); @@ -1824,6 +1842,7 @@ ep_rt_wait_event_get_wait_handle (ep_rt_wait_event_handle_t *wait_event) STATIC_CONTRACT_NOTHROW; EP_ASSERT (wait_event != NULL && wait_event->event != NULL); + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: NativeAOT CLREventStatic doesn't have GetHandleUNHOSTED PalDebugBreak(); return 0; @@ -1886,9 +1905,11 @@ ep_rt_create_activity_id ( EP_ASSERT (activity_id != NULL); EP_ASSERT (activity_id_len == EP_ACTIVITY_ID_SIZE); + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implement a way to generate a real Guid // CoCreateGuid (reinterpret_cast(activity_id)); + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Using roughly Mono's implementation but Mono randomly generates this, hardcoding for now uint8_t data1[] = {0x67,0xac,0x33,0xf1,0x8d,0xed,0x41,0x01,0xb4,0x26,0xc9,0xb7,0x94,0x35,0xf7,0x8a}; memcpy (activity_id, data1, EP_ACTIVITY_ID_SIZE); @@ -1923,6 +1944,7 @@ bool ep_rt_is_running (void) { STATIC_CONTRACT_NOTHROW; + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Does NativeAot have the concept of EEStarted PalDebugBreak(); @@ -1937,6 +1959,7 @@ ep_rt_execute_rundown (ep_rt_execution_checkpoint_array_t *execution_checkpoints STATIC_CONTRACT_NOTHROW; //TODO: Write execution checkpoint rundown events. + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: EventPipe Configuration values - RhConfig? // (CLRConfig::INTERNAL_EventPipeCircularMB) PalDebugBreak(); @@ -1975,6 +1998,7 @@ EP_RT_DEFINE_THREAD_FUNC (ep_rt_thread_aot_start_session_or_sampling_thread) ep_rt_thread_params_t* thread_params = reinterpret_cast(data); + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implement thread creation/management if needed. // The session and sampling threads both assert that the incoming thread handle is // non-null, but do not necessarily rely on it otherwise; just pass a meaningless non-null @@ -1997,6 +2021,7 @@ ep_rt_thread_create ( STATIC_CONTRACT_NOTHROW; EP_ASSERT (thread_func != NULL); + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Fill in the outgoing id if any callers ever need it if (id) *reinterpret_cast(id) = 0xffffffff; @@ -2027,48 +2052,6 @@ ep_rt_thread_create ( return true; } - - // Mono implementation -/** - rt_mono_thread_params_internal_t *thread_params = g_new0 (rt_mono_thread_params_internal_t, 1); - if (thread_params) { - thread_params->thread_params.thread_type = thread_type; - thread_params->thread_params.thread_func = (ep_rt_thread_start_func)thread_func; - thread_params->thread_params.thread_params = params; - thread_params->background_thread = true; - return (mono_thread_platform_create_thread (ep_rt_thread_mono_start_func, thread_params, NULL, (ep_rt_thread_id_t *)id) == TRUE) ? true : false; - } - - return false; - - * */ - - // CoreCLR implementation - - // if (thread_params) { - // thread_params->thread_params.thread_type = thread_type; - // if (thread_type == EP_THREAD_TYPE_SESSION || thread_type == EP_THREAD_TYPE_SAMPLING) { - // thread_params->thread_params.thread = SetupUnstartedThread (); - // thread_params->thread_params.thread_func = reinterpret_cast(thread_func); - // thread_params->thread_params.thread_params = params; - // if (thread_params->thread_params.thread->CreateNewThread (0, ep_rt_thread_aot_start_func, thread_params)) { - // thread_params->thread_params.thread->SetBackground (TRUE); - // thread_params->thread_params.thread->StartThread (); - // if (id) - // *reinterpret_cast(id) = thread_params->thread_params.thread->GetThreadId (); - // result = true; - // } - // } else if (thread_type == EP_THREAD_TYPE_SERVER) { - // DWORD thread_id = 0; - // HANDLE server_thread = ::CreateThread (nullptr, 0, reinterpret_cast(thread_func), nullptr, 0, &thread_id); - // if (server_thread != NULL) { - // ::CloseHandle (server_thread); - // if (id) - // *reinterpret_cast(id) = thread_id; - // result = true; - // } - // } - // } } static @@ -2076,6 +2059,7 @@ inline void ep_rt_set_server_name(void) { + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Need to set name for the thread // ::SetThreadName(GetCurrentThread(), W(".NET EventPipe")); } @@ -2142,6 +2126,7 @@ ep_rt_current_thread_get_id (void) STATIC_CONTRACT_NOTHROW; #ifdef TARGET_UNIX + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: AOT doesn't have PAL_GetCurrentOSThreadId, as CoreCLR does. PalDebugBreak(); return static_cast(0); @@ -2191,6 +2176,7 @@ ep_rt_system_time_get (EventPipeSystemTime *system_time) value.wSecond, value.wMilliseconds); #else + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Get System time PalDebugBreak(); #endif @@ -2239,6 +2225,7 @@ ep_rt_file_open_write (const ep_char8_t *path) ep_char16_t *path_utf16 = ep_rt_utf8_to_utf16le_string (path, -1); ep_return_null_if_nok (path_utf16 != NULL); + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Find out the way to open a file in native PalDebugBreak(); @@ -2252,6 +2239,7 @@ ep_rt_file_close (ep_rt_file_handle_t file_handle) { STATIC_CONTRACT_NOTHROW; + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Find out the way to close a file in native PalDebugBreak(); return true; @@ -2269,6 +2257,7 @@ ep_rt_file_write ( STATIC_CONTRACT_NOTHROW; EP_ASSERT (buffer != NULL); + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Find out the way to write to a file in native PalDebugBreak(); @@ -2320,15 +2309,6 @@ ep_rt_os_environment_get_utf16 (ep_rt_env_array_utf16_t *env_array) STATIC_CONTRACT_NOTHROW; EP_ASSERT (env_array != NULL); - // LPWSTR envs = GetEnvironmentStringsW (); - // if (envs) { - // LPWSTR next = envs; - // while (*next) { - // ep_rt_env_array_utf16_append (env_array, ep_rt_utf16_string_dup (reinterpret_cast(next))); - // next += ep_rt_utf16_string_len (reinterpret_cast(next)) + 1; - // } - // FreeEnvironmentStringsW (envs); - // } PalDebugBreak(); } @@ -2343,6 +2323,7 @@ ep_rt_lock_acquire (ep_rt_lock_handle_t *lock) STATIC_CONTRACT_NOTHROW; bool result = true; + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implement EventPipe locking for NativeAOT return result; @@ -2355,6 +2336,7 @@ ep_rt_lock_release (ep_rt_lock_handle_t *lock) STATIC_CONTRACT_NOTHROW; bool result = true; + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implement EventPipe locking for NativeAOT return result; @@ -2415,6 +2397,7 @@ ep_rt_spin_lock_acquire (ep_rt_spin_lock_handle_t *spin_lock) STATIC_CONTRACT_NOTHROW; EP_ASSERT (ep_rt_spin_lock_is_valid (spin_lock)); + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implement locking (maybe by making the manual Lock and Unlock functions public) // SpinLock::Lock (*(spin_lock->lock)); return true; @@ -2428,6 +2411,7 @@ ep_rt_spin_lock_release (ep_rt_spin_lock_handle_t *spin_lock) STATIC_CONTRACT_NOTHROW; EP_ASSERT (ep_rt_spin_lock_is_valid (spin_lock)); + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implement locking (maybe by making the manual Lock and Unlock functions public) // SpinLock::Unlock (*(spin_lock->lock)); return true; @@ -2610,6 +2594,7 @@ ep_rt_utf8_to_utf16le_string ( if (!str) return NULL; + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implementation would just use strlen and malloc to make a new buffer, and would then copy the string chars one by one size_t len_utf8 = strlen(str); if (len_utf8 == 0) @@ -2678,6 +2663,7 @@ ep_rt_utf16_to_utf8_string ( if (!str) return NULL; + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Temp implementation that is the reverse of ep_rt_utf8_to_utf16le_string size_t len_utf16 = len; if(len_utf16 == -1) @@ -2737,6 +2723,7 @@ ep_rt_diagnostics_command_line_get (void) STATIC_CONTRACT_NOTHROW; + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: revisit commandline for AOT // return reinterpret_cast(::GetCommandLineA()); @@ -2819,6 +2806,7 @@ ep_rt_thread_setup (void) { STATIC_CONTRACT_NOTHROW; + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implement thread creation/management if needed // Thread* thread_handle = SetupThreadNoThrow (); // EP_ASSERT (thread_handle != NULL); @@ -2855,6 +2843,7 @@ ep_rt_thread_handle_t ep_rt_thread_get_handle (void) { STATIC_CONTRACT_NOTHROW; + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implement thread creation/management if needed // return GetThreadNULLOk (); return NULL; @@ -2868,6 +2857,7 @@ ep_rt_thread_get_id (ep_rt_thread_handle_t thread_handle) STATIC_CONTRACT_NOTHROW; EP_ASSERT (thread_handle != NULL); + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implement thread creation/management if needed // return ep_rt_uint64_t_to_thread_id_t (thread_handle->GetOSThreadId64 ()); PalDebugBreak(); @@ -2896,6 +2886,7 @@ bool ep_rt_thread_has_started (ep_rt_thread_handle_t thread_handle) { STATIC_CONTRACT_NOTHROW; + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implement thread creation/management if needed // return thread_handle != NULL && thread_handle->HasStarted (); return true; @@ -2907,6 +2898,7 @@ ep_rt_thread_activity_id_handle_t ep_rt_thread_get_activity_id_handle (void) { STATIC_CONTRACT_NOTHROW; + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implement thread creation/management if needed // return GetThread (); PalDebugBreak(); @@ -2921,6 +2913,7 @@ ep_rt_thread_get_activity_id_cref (ep_rt_thread_activity_id_handle_t activity_id STATIC_CONTRACT_NOTHROW; EP_ASSERT (activity_id_handle != NULL); + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implement thread creation/management if needed // return reinterpret_cast(activity_id_handle->GetActivityId ()); PalDebugBreak(); @@ -2956,6 +2949,7 @@ ep_rt_thread_set_activity_id ( EP_ASSERT (activity_id != NULL); EP_ASSERT (activity_id_len == EP_ACTIVITY_ID_SIZE); + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implement thread creation/management if needed // activity_id_handle->SetActivityId (reinterpret_cast(activity_id)); PalDebugBreak(); diff --git a/src/coreclr/nativeaot/Runtime/eventpipeadapter.h b/src/coreclr/nativeaot/Runtime/eventpipeadapter.h index 2d76e9aabcfdb..d580ca3fa5d38 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipeadapter.h +++ b/src/coreclr/nativeaot/Runtime/eventpipeadapter.h @@ -17,141 +17,6 @@ #include #include - -#if defined(NATIVEAOT_CORPROF_INCLUDE_IS_READY) - -class EventPipeProviderConfigurationAdapter final -{ -public: - EventPipeProviderConfigurationAdapter(const COR_PRF_EVENTPIPE_PROVIDER_CONFIG *providerConfigs, uint32_t providerConfigsLen) - { - STATIC_CONTRACT_NOTHROW; - - // This static_assert will fail because EventPipeProviderConfiguration uses char8_t strings rather than char16_t strings. - // This method takes the COR_PRF variant and converts to char8_t strings, so it should be fine. - // Leaving the assert commented out here for posterity. - // - // static_assert(offsetof(EventPipeProviderConfiguration, provider_name) == offsetof(COR_PRF_EVENTPIPE_PROVIDER_CONFIG, providerName) - // && offsetof(EventPipeProviderConfiguration, keywords) == offsetof(COR_PRF_EVENTPIPE_PROVIDER_CONFIG, keywords) - // && offsetof(EventPipeProviderConfiguration, logging_level) == offsetof(COR_PRF_EVENTPIPE_PROVIDER_CONFIG, loggingLevel) - // && offsetof(EventPipeProviderConfiguration, filter_data) == offsetof(COR_PRF_EVENTPIPE_PROVIDER_CONFIG, filterData) - // && sizeof(EventPipeProviderConfiguration) == sizeof(COR_PRF_EVENTPIPE_PROVIDER_CONFIG), - // "Layouts of EventPipeProviderConfiguration type and COR_PRF_EVENTPIPE_PROVIDER_CONFIG type do not match!"); - - m_providerConfigs = new (nothrow) EventPipeProviderConfiguration[providerConfigsLen]; - m_providerConfigsLen = providerConfigsLen; - if (m_providerConfigs) { - for (uint32_t i = 0; i < providerConfigsLen; ++i) { - ep_provider_config_init ( - &m_providerConfigs[i], - ep_rt_utf16_to_utf8_string (reinterpret_cast(providerConfigs[i].providerName), -1), - providerConfigs[i].keywords, - static_cast(providerConfigs[i].loggingLevel), - ep_rt_utf16_to_utf8_string (reinterpret_cast(providerConfigs[i].filterData), -1)); - } - } - } - - ~EventPipeProviderConfigurationAdapter() - { - STATIC_CONTRACT_NOTHROW; - if (m_providerConfigs) { - for (uint32_t i = 0; i < m_providerConfigsLen; ++i) { - ep_rt_utf8_string_free ((ep_char8_t *)ep_provider_config_get_provider_name (&m_providerConfigs[i])); - ep_rt_utf8_string_free ((ep_char8_t *)ep_provider_config_get_filter_data (&m_providerConfigs[i])); - } - delete [] m_providerConfigs; - } - } - - inline const EventPipeProviderConfiguration * GetProviderConfigs() const - { - STATIC_CONTRACT_NOTHROW; - return m_providerConfigs; - } - - inline uint32_t GetProviderConfigsLen() const - { - STATIC_CONTRACT_NOTHROW; - return m_providerConfigsLen; - } - -private: - EventPipeProviderConfiguration *m_providerConfigs; - uint32_t m_providerConfigsLen; -}; - -class EventPipeParameterDescAdapter final -{ -public: - EventPipeParameterDescAdapter(COR_PRF_EVENTPIPE_PARAM_DESC *params, uint32_t paramsLen) - { - STATIC_CONTRACT_NOTHROW; - -#ifdef EP_INLINE_GETTER_SETTER - static_assert(offsetof(EventPipeParameterDesc, type) == offsetof(COR_PRF_EVENTPIPE_PARAM_DESC, type) - && offsetof(EventPipeParameterDesc, element_type) == offsetof(COR_PRF_EVENTPIPE_PARAM_DESC, elementType) - && offsetof(EventPipeParameterDesc, name) == offsetof(COR_PRF_EVENTPIPE_PARAM_DESC, name) - && sizeof(EventPipeParameterDesc) == sizeof(COR_PRF_EVENTPIPE_PARAM_DESC), - "Layouts of EventPipeParameterDesc type and COR_PRF_EVENTPIPE_PARAM_DESC type do not match!"); -#endif - m_params = reinterpret_cast(params); - m_paramsLen = paramsLen; - } - - inline const EventPipeParameterDesc * GetParams() const - { - STATIC_CONTRACT_NOTHROW; - return m_params; - } - - inline uint32_t GetParamsLen() const - { - STATIC_CONTRACT_NOTHROW; - return m_paramsLen; - } - -private: - EventPipeParameterDesc *m_params; - uint32_t m_paramsLen; -}; - -class EventDataAdapter final -{ -public: - EventDataAdapter(COR_PRF_EVENT_DATA *data, uint32_t dataLen) - { - STATIC_CONTRACT_NOTHROW; - -#ifdef EP_INLINE_GETTER_SETTER - static_assert(offsetof(EventData, ptr) == offsetof(COR_PRF_EVENT_DATA, ptr) - && offsetof(EventData, size) == offsetof(COR_PRF_EVENT_DATA, size) - && sizeof(EventData) == sizeof(COR_PRF_EVENT_DATA), - "Layouts of EventData type and COR_PRF_EVENT_DATA type do not match!"); -#endif - m_data = reinterpret_cast(data); - m_dataLen = dataLen; - } - - inline const EventData * GetData() const - { - STATIC_CONTRACT_NOTHROW; - return m_data; - } - - inline uint32_t GetDataLen() const - { - STATIC_CONTRACT_NOTHROW; - return m_dataLen; - } - -private: - EventData *m_data; - uint32_t m_dataLen; -}; - -#endif // defined(NATIVEAOT_CORPROF_INCLUDE_IS_READY) - class EventPipeAdapter final { public: @@ -202,45 +67,6 @@ class EventPipeAdapter final return ep_enabled(); } -#if defined(NATIVEAOT_CORPROF_INCLUDE_IS_READY) - static inline EventPipeSessionID Enable( - LPCWSTR outputPath, - uint32_t circularBufferSizeInMB, - const EventPipeProviderConfigurationAdapter &providerConfigs, - EventPipeSessionType sessionType, - EventPipeSerializationFormat format, - const bool rundownRequested, - IpcStream *const stream, - EventPipeSessionSynchronousCallback callback, - void *callbackAdditionalData) - { - CONTRACTL - { - NOTHROW; - GC_TRIGGERS; - MODE_PREEMPTIVE; - } - CONTRACTL_END; - - ep_char8_t *outputPathUTF8 = NULL; - if (outputPath) - outputPathUTF8 = ep_rt_utf16_to_utf8_string (reinterpret_cast(outputPath), -1); - EventPipeSessionID result = ep_enable ( - outputPathUTF8, - circularBufferSizeInMB, - providerConfigs.GetProviderConfigs(), - providerConfigs.GetProviderConfigsLen(), - sessionType, - format, - rundownRequested, - stream, - callback, - callbackAdditionalData); - ep_rt_utf8_string_free (outputPathUTF8); - return result; - } -#endif // defined(NATIVEAOT_CORPROF_INCLUDE_IS_READY) - static inline void Disable(EventPipeSessionID id) { CONTRACTL @@ -254,84 +80,6 @@ class EventPipeAdapter final ep_disable(id); } -#if defined(NATIVEAOT_CORPROF_INCLUDE_IS_READY) - static inline void StartStreaming(EventPipeSessionID id) - { - CONTRACTL - { - NOTHROW; - GC_TRIGGERS; - MODE_ANY; - } - CONTRACTL_END; - - ep_start_streaming(id); - } - - static inline EventPipeSession * GetSession(EventPipeSessionID id) - { - STATIC_CONTRACT_NOTHROW; - return ep_get_session(id); - } - - static inline bool SignalSession(EventPipeSessionID id) - { - STATIC_CONTRACT_NOTHROW; - - EventPipeSession *const session = ep_get_session (id); - if (!session) - return false; - - return ep_rt_wait_event_set (ep_session_get_wait_event (session)); - } - - static inline bool WaitForSessionSignal(EventPipeSessionID id, INT32 timeoutMs) - { - STATIC_CONTRACT_NOTHROW; - - EventPipeSession *const session = ep_get_session (id); - if (!session) - return false; - - return !ep_rt_wait_event_wait (ep_session_get_wait_event (session), (uint32_t)timeoutMs, false) ? true : false; - } - - static inline FILETIME GetSessionStartTime(EventPipeSession *session) - { - STATIC_CONTRACT_NOTHROW; - - FILETIME fileTime; - LARGE_INTEGER largeValue; - - _ASSERTE(session != NULL); - largeValue.QuadPart = ep_session_get_session_start_time(session); - fileTime.dwLowDateTime = largeValue.u.LowPart; - fileTime.dwHighDateTime = largeValue.u.HighPart; - return fileTime; - } - - static inline LONGLONG GetSessionStartTimestamp(EventPipeSession *session) - { - STATIC_CONTRACT_NOTHROW; - - _ASSERTE(session != NULL); - return ep_session_get_session_start_timestamp(session); - } - - static inline void AddProviderToSession(EventPipeSessionProvider *provider, EventPipeSession *session) - { - CONTRACTL - { - NOTHROW; - GC_TRIGGERS; - MODE_PREEMPTIVE; - } - CONTRACTL_END; - - ep_add_provider_to_session (provider, session); - } -#endif // defined(NATIVEAOT_CORPROF_INCLUDE_IS_READY) - static inline EventPipeProvider * GetProvider (LPCWSTR providerName) { CONTRACTL @@ -351,96 +99,6 @@ class EventPipeAdapter final return provider; } -#if defined(NATIVEAOT_CORPROF_INCLUDE_IS_READY) - static EventPipeSessionProvider * CreateSessionProvider(const EventPipeProviderConfigurationAdapter &providerConfig) - { - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - _ASSERTE (providerConfig.GetProviderConfigs() != NULL && providerConfig.GetProviderConfigsLen() == 1); - const EventPipeProviderConfiguration *config = providerConfig.GetProviderConfigs(); - if (!config) - return NULL; - - return ep_session_provider_alloc ( - ep_provider_config_get_provider_name (&config[0]), - ep_provider_config_get_keywords (&config[0]), - (EventPipeEventLevel)ep_provider_config_get_logging_level (&config[0]), - ep_provider_config_get_filter_data (&config[0])); - } - - static HRESULT GetProviderName(const EventPipeProvider *provider, ULONG numNameChars, ULONG *numNameCharsOut, LPWSTR name) - { - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - _ASSERTE(provider != NULL); - - HRESULT hr = S_OK; - const ep_char16_t *providerName = ep_provider_get_provider_name_utf16 (provider); - if (providerName) { - uint32_t numProviderNameChars = (uint32_t)(ep_rt_utf16_string_len (providerName) + 1); - if (numNameCharsOut) - *numNameCharsOut = numProviderNameChars; - if (numProviderNameChars >= numNameChars) - hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); - else if (name) - memcpy (name, providerName, numProviderNameChars * sizeof (ep_char16_t)); - } - return hr; - } - - static EventPipeEvent * AddEvent( - EventPipeProvider *provider, - uint32_t eventID, - LPCWSTR eventName, - int64_t keywords, - uint32_t eventVersion, - EventPipeEventLevel level, - uint8_t opcode, - const EventPipeParameterDescAdapter ¶ms, - bool needStack) - { - - size_t metadataLen = 0; - EventPipeEvent *realEvent = NULL; - uint8_t *metadata = ep_metadata_generator_generate_event_metadata ( - eventID, - reinterpret_cast(eventName), - keywords, - eventVersion, - level, - opcode, - (EventPipeParameterDesc *)params.GetParams(), - params.GetParamsLen(), - &metadataLen); - if (metadata) { - realEvent = ep_provider_add_event( - provider, - eventID, - keywords, - eventVersion, - level, - needStack, - metadata, - (uint32_t)metadataLen); - ep_rt_byte_array_free(metadata); - } - return realEvent; - } - -#endif // defined(NATIVEAOT_CORPROF_INCLUDE_IS_READY) - static inline EventPipeEvent * AddEvent( EventPipeProvider *provider, uint32_t eventID, @@ -483,105 +141,6 @@ class EventPipeAdapter final reinterpret_cast(activityId), reinterpret_cast(relatedActivityId)); } - -#if defined(NATIVEAOT_CORPROF_INCLUDE_IS_READY) - static inline void WriteEvent( - EventPipeEvent *ep_event, - EventDataAdapter &data, - const GUID * activityId, - const GUID * relatedActivityId) - { - WriteEvent( - ep_event, - (EventData*)data.GetData(), - data.GetDataLen(), - activityId, - relatedActivityId); - } - - static inline bool EventIsEnabled (const EventPipeEvent *epEvent) - { - STATIC_CONTRACT_NOTHROW; - return ep_event_is_enabled(epEvent); - } - - static inline EventPipeEventInstance * GetNextEvent (EventPipeSessionID id) - { - CONTRACTL - { - NOTHROW; - GC_TRIGGERS; - MODE_PREEMPTIVE; - } - CONTRACTL_END; - - return ep_get_next_event(id); - } - - static inline EventPipeProvider * GetEventProvider (EventPipeEventInstance *eventInstance) - { - STATIC_CONTRACT_NOTHROW; - return ep_event_get_provider(ep_event_instance_get_ep_event(eventInstance)); - } - - static inline uint32_t GetEventID (EventPipeEventInstance *eventInstance) - { - STATIC_CONTRACT_NOTHROW; - return ep_event_get_event_id(ep_event_instance_get_ep_event(eventInstance)); - } - - static inline uint64_t GetEventThreadID (EventPipeEventInstance *eventInstance) - { - STATIC_CONTRACT_NOTHROW; - return ep_event_instance_get_thread_id(eventInstance); - } - - static inline int64_t GetEventTimestamp (EventPipeEventInstance *eventInstance) - { - STATIC_CONTRACT_NOTHROW; - return ep_event_instance_get_timestamp(eventInstance); - } - - static inline LPCGUID GetEventActivityID (EventPipeEventInstance *eventInstance) - { - STATIC_CONTRACT_NOTHROW; - static_assert(sizeof(GUID) == EP_ACTIVITY_ID_SIZE, "Size mismatch, sizeof(GUID) should be equal to EP_ACTIVITY_ID_SIZE"); - return reinterpret_cast(ep_event_instance_get_activity_id_cref(eventInstance)); - } - - static inline LPCGUID GetEventRelativeActivityID (EventPipeEventInstance *eventInstance) - { - STATIC_CONTRACT_NOTHROW; - static_assert(sizeof(GUID) == EP_ACTIVITY_ID_SIZE, "Size mismatch, sizeof(GUID) should be equal to EP_ACTIVITY_ID_SIZE"); - return reinterpret_cast(ep_event_instance_get_related_activity_id_cref(eventInstance)); - } - - static inline const uint8_t * GetEventData (EventPipeEventInstance *eventInstance) - { - STATIC_CONTRACT_NOTHROW; - return ep_event_instance_get_data(eventInstance); - } - - static inline uint32_t GetEventDataLen (EventPipeEventInstance *eventInstance) - { - STATIC_CONTRACT_NOTHROW; - return ep_event_instance_get_data_len(eventInstance); - } - - static inline void ResumeSession (EventPipeSession *session) - { - STATIC_CONTRACT_NOTHROW; - ep_session_resume (session); - } - - static inline void PauseSession (EventPipeSession *session) - { - STATIC_CONTRACT_NOTHROW; - ep_session_pause (session); - } - -#endif // defined(NATIVEAOT_CORPROF_INCLUDE_IS_READY) - }; #endif // FEATURE_PERFTRACING diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs index ee3d499e85896..aceb18c78449e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs @@ -36,7 +36,7 @@ public static class Keywords private PollingCounter? _timerCounter; private PollingCounter? _fragmentationCounter; -#if !NATIVEAOT // TODO +#if !NATIVEAOT // TODO shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase private PollingCounter? _committedCounter; private IncrementingPollingCounter? _exceptionCounter; private PollingCounter? _gcTimeCounter; diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Overlapped.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Overlapped.cs index a97bf7464ec3b..45f17feec6da0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Overlapped.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Overlapped.cs @@ -185,7 +185,7 @@ public static void Free(NativeOverlapped* nativeOverlappedPtr) #if FEATURE_PERFTRACING #if !((TARGET_BROWSER || TARGET_WASI) && !FEATURE_WASM_THREADS) -#if !NATIVEAOT +#if !NATIVEAOT // TODO shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase if (NativeRuntimeEventSource.Log.IsEnabled()) NativeRuntimeEventSource.Log.ThreadPoolIOPack(pNativeOverlapped); #endif diff --git a/src/native/eventpipe/ds-ipc-pal-namedpipe.h b/src/native/eventpipe/ds-ipc-pal-namedpipe.h index fec28bcd1ccce..6952ccc17aca5 100644 --- a/src/native/eventpipe/ds-ipc-pal-namedpipe.h +++ b/src/native/eventpipe/ds-ipc-pal-namedpipe.h @@ -1,9 +1,6 @@ #ifndef __DIAGNOSTICS_IPC_PAL_NAMEDPIPE_H__ #define __DIAGNOSTICS_IPC_PAL_NAMEDPIPE_H__ -#undef __AOT_WINDOWS_DEF_NOT_NEEDED___ -#define __AOT_WINDOWS_DEF_NOT_NEEDED___ - #include "ds-rt-config.h" #ifdef ENABLE_PERFTRACING diff --git a/src/tests/tracing/eventpipe/common/IpcTraceTest.cs b/src/tests/tracing/eventpipe/common/IpcTraceTest.cs index 49e6e2774f8f4..cab3b5df98bab 100644 --- a/src/tests/tracing/eventpipe/common/IpcTraceTest.cs +++ b/src/tests/tracing/eventpipe/common/IpcTraceTest.cs @@ -212,7 +212,11 @@ private int Validate() Logger.logger.Log("Connecting to EventPipe..."); try { +#if EnableNativeEventPipe + _eventPipeSession = client.StartEventPipeSession(_testProviders.Concat(_sentinelProviders), false); +#else _eventPipeSession = client.StartEventPipeSession(_testProviders.Concat(_sentinelProviders)); +#endif } catch (DiagnosticsClientException ex) { diff --git a/src/tests/tracing/eventpipe/providervalidation/providervalidation.cs b/src/tests/tracing/eventpipe/providervalidation/providervalidation.cs index 2da95c1523960..9b509c723e9fa 100644 --- a/src/tests/tracing/eventpipe/providervalidation/providervalidation.cs +++ b/src/tests/tracing/eventpipe/providervalidation/providervalidation.cs @@ -44,19 +44,29 @@ public static int Main() private static Dictionary _expectedEventCounts = new Dictionary() { +#if EnableNativeEventPipe + { "MyEventSource", 1 }, + { "Microsoft-DotNETCore-EventPipe", 1} +#else { "MyEventSource", new ExpectedEventCount(100_000, 0.30f) }, { "Microsoft-Windows-DotNETRuntimeRundown", -1 }, { "Microsoft-DotNETCore-SampleProfiler", -1 } +#endif }; private static Action _eventGeneratingAction = () => { +#if EnableNativeEventPipe + Logger.logger.Log($"Firing an event..."); + MyEventSource.Log.MyEvent(); +#else for (int i = 0; i < 100_000; i++) { if (i % 10_000 == 0) Logger.logger.Log($"Fired MyEvent {i:N0}/100,000 times..."); MyEventSource.Log.MyEvent(); } +#endif }; } } diff --git a/src/tests/tracing/eventpipe/providervalidation/providervalidation.csproj b/src/tests/tracing/eventpipe/providervalidation/providervalidation.csproj index 8a67dfd70a8fc..69af1e14f75ce 100644 --- a/src/tests/tracing/eventpipe/providervalidation/providervalidation.csproj +++ b/src/tests/tracing/eventpipe/providervalidation/providervalidation.csproj @@ -6,6 +6,8 @@ true true true + From 9b17dd22b653229056767cadce59ea522f570159 Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Mon, 30 Jan 2023 04:45:00 -0800 Subject: [PATCH 24/32] Update src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Michal Strehovský --- .../BuildIntegration/Microsoft.NETCore.Native.Windows.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets index 735732dcd5126..5c115640adc8d 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets @@ -35,7 +35,7 @@ The .NET Foundation licenses this file to you under the MIT license. - + From 34a44c40ed4af080f8a6fe79518b010ed33ef1f4 Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Tue, 31 Jan 2023 09:27:12 -0800 Subject: [PATCH 25/32] Added GuardCF version and a standalone test --- src/coreclr/nativeaot/Runtime/CMakeLists.txt | 61 ++++++++++++++++++- .../nativeaot/Runtime/Full/CMakeLists.txt | 5 ++ .../reproNative/reproNative.vcxproj | 6 +- .../tracing/eventpipe/common/IpcTraceTest.cs | 13 ++-- .../providervalidation/providervalidation.cs | 10 --- .../providervalidation.csproj | 2 - .../Simpleprovidervalidation.cs | 57 +++++++++++++++++ .../simpleprovidervalidation.csproj | 17 ++++++ 8 files changed, 145 insertions(+), 26 deletions(-) create mode 100644 src/tests/tracing/eventpipe/simpleprovidervalidation/Simpleprovidervalidation.cs create mode 100644 src/tests/tracing/eventpipe/simpleprovidervalidation/simpleprovidervalidation.csproj diff --git a/src/coreclr/nativeaot/Runtime/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/CMakeLists.txt index d3c7e55188646..6a9a034be4460 100644 --- a/src/coreclr/nativeaot/Runtime/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/CMakeLists.txt @@ -11,12 +11,67 @@ include_directories(${SHARED_EVENTPIPE_SOURCE_DIR}) set (AOT_EVENTPIPE_SHIM_SOURCES "") set (AOT_EVENTPIPE_SHIM_HEADERS "") set (AOT_EVENTPIPE_MANAGED_TO_NATIVE_SOURCES "") +set (SHARED_EVENTPIPE_SOURCES "") +set (SHARED_EVENTPIPE_HEADERS "") set (SHARED_DIAGNOSTIC_SERVER_SOURCES "") set (SHARED_DIAGNOSTIC_SERVER_HEADERS "") set (AOT_EVENTPIPE_DISABLED_SOURCES "") -set (SHARED_EVENTPIPE_SOURCE_PATH "${CLR_SRC_NATIVE_DIR}/eventpipe") -include (${SHARED_EVENTPIPE_SOURCE_PATH}/CMakeLists.txt) +list(APPEND SHARED_EVENTPIPE_SOURCES + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-sources.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-block.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-buffer.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-buffer-manager.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-config.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event-instance.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event-payload.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event-source.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-file.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-json-file.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-metadata-generator.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-provider.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-sample-profiler.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-session.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-session-provider.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-stack-contents.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-stream.c + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-thread.c +) + +list(APPEND SHARED_EVENTPIPE_HEADERS + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-block.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-buffer.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-buffer-manager.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-config.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-config-internals.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event-instance.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event-payload.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event-source.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-file.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-getter-setter.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-ipc-pal-types.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-ipc-pal-types-forward.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-ipc-stream.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-json-file.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-metadata-generator.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-provider.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-provider-internals.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-rt.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-rt-config.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-rt-types.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-sample-profiler.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-session.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-session-provider.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-stack-contents.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-stream.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-thread.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-types.h + ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-types-forward.h +) list(APPEND SHARED_DIAGNOSTIC_SERVER_SOURCES ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-sources.c @@ -349,4 +404,4 @@ if(NOT CLR_CMAKE_TARGET_ARCH_WASM) add_subdirectory(Full) else() add_subdirectory(Portable) -endif() +endif() \ No newline at end of file diff --git a/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt index 2fdca83c79723..c2088b3ddcc04 100644 --- a/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt @@ -34,6 +34,10 @@ if (CLR_CMAKE_TARGET_WIN32) add_library(Runtime.ServerGC.GuardCF STATIC ${COMMON_RUNTIME_SOURCES} ${FULL_RUNTIME_SOURCES} ${RUNTIME_SOURCES_ARCH_ASM} ${SERVER_GC_SOURCES} ${RUNTIME_ARCH_ASM_OBJECTS}) target_compile_definitions(Runtime.ServerGC.GuardCF PRIVATE -DFEATURE_SVR_GC) target_compile_options(Runtime.ServerGC.GuardCF PRIVATE $<$,$>:/guard:cf>) + + add_library(eventpipe-disabled.GuardCF STATIC ${AOT_EVENTPIPE_DISABLED_SOURCES}) + install_static_library(eventpipe-disabled.GuardCF aotsdk nativeaot) + target_compile_options(eventpipe-disabled.GuardCF PRIVATE $<$,$>:/guard:cf>) endif (CLR_CMAKE_TARGET_WIN32) # Get the current list of definitions @@ -101,4 +105,5 @@ install_static_library(eventpipe-enabled aotsdk nativeaot) install_static_library(eventpipe-disabled aotsdk nativeaot) if (CLR_CMAKE_TARGET_WIN32) install_static_library(Runtime.ServerGC.GuardCF aotsdk nativeaot) + install_static_library(eventpipe-disabled.GuardCF aotsdk nativeaot) endif (CLR_CMAKE_TARGET_WIN32) diff --git a/src/coreclr/tools/aot/ILCompiler/reproNative/reproNative.vcxproj b/src/coreclr/tools/aot/ILCompiler/reproNative/reproNative.vcxproj index ee8d32964d805..26251393ffa3e 100644 --- a/src/coreclr/tools/aot/ILCompiler/reproNative/reproNative.vcxproj +++ b/src/coreclr/tools/aot/ILCompiler/reproNative/reproNative.vcxproj @@ -81,7 +81,7 @@ Console true - $(ArtifactsRoot)bin\repro\x64\Debug\repro.obj;$(Win32SDKLibs);%(AdditionalDependencies);$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\Runtime.WorkstationGC.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\System.Globalization.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\System.IO.Compression.Native.Aot.lib + $(ArtifactsRoot)bin\repro\x64\Debug\repro.obj;$(Win32SDKLibs);%(AdditionalDependencies);$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\Runtime.WorkstationGC.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\System.Globalization.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\System.IO.Compression.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Debug\aotsdk\eventpipe-disabled.lib @@ -101,7 +101,7 @@ true true true - $(ArtifactsRoot)bin\repro\x64\Checked\repro.obj;$(Win32SDKLibs);%(AdditionalDependencies);$(ArtifactsRoot)bin\coreclr\windows.x64.Checked\aotsdk\Runtime.WorkstationGC.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Checked\aotsdk\System.Globalization.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Checked\aotsdk\System.IO.Compression.Native.Aot.lib + $(ArtifactsRoot)bin\repro\x64\Checked\repro.obj;$(Win32SDKLibs);%(AdditionalDependencies);$(ArtifactsRoot)bin\coreclr\windows.x64.Checked\aotsdk\Runtime.WorkstationGC.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Checked\aotsdk\System.Globalization.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Checked\aotsdk\System.IO.Compression.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Checked\aotsdk\eventpipe-disabled.lib @@ -121,7 +121,7 @@ true true true - $(ArtifactsRoot)bin\repro\x64\Release\repro.obj;$(Win32SDKLibs);%(AdditionalDependencies);$(ArtifactsRoot)bin\coreclr\windows.x64.Release\aotsdk\Runtime.WorkstationGC.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Release\aotsdk\System.Globalization.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Release\aotsdk\System.IO.Compression.Native.Aot.lib + $(ArtifactsRoot)bin\repro\x64\Release\repro.obj;$(Win32SDKLibs);%(AdditionalDependencies);$(ArtifactsRoot)bin\coreclr\windows.x64.Release\aotsdk\Runtime.WorkstationGC.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Release\aotsdk\System.Globalization.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Release\aotsdk\System.IO.Compression.Native.Aot.lib;$(ArtifactsRoot)bin\coreclr\windows.x64.Release\aotsdk\eventpipe-disabled.lib diff --git a/src/tests/tracing/eventpipe/common/IpcTraceTest.cs b/src/tests/tracing/eventpipe/common/IpcTraceTest.cs index cab3b5df98bab..17c0562675bc8 100644 --- a/src/tests/tracing/eventpipe/common/IpcTraceTest.cs +++ b/src/tests/tracing/eventpipe/common/IpcTraceTest.cs @@ -167,7 +167,7 @@ private int Fail(string message = "") return -1; } - private int Validate() + private int Validate(bool enableRundownProvider = true) { // FIXME: This is a bandaid fix for a deadlock in EventPipeEventSource caused by // the lazy caching in the Regex library. The caching creates a ConcurrentDictionary @@ -212,11 +212,7 @@ private int Validate() Logger.logger.Log("Connecting to EventPipe..."); try { -#if EnableNativeEventPipe - _eventPipeSession = client.StartEventPipeSession(_testProviders.Concat(_sentinelProviders), false); -#else - _eventPipeSession = client.StartEventPipeSession(_testProviders.Concat(_sentinelProviders)); -#endif + _eventPipeSession = client.StartEventPipeSession(_testProviders.Concat(_sentinelProviders), enableRundownProvider); } catch (DiagnosticsClientException ex) { @@ -396,13 +392,14 @@ public static int RunAndValidateEventCounts( Action eventGeneratingAction, List providers, int circularBufferMB=1024, - Func> optionalTraceValidator = null) + Func> optionalTraceValidator = null, + bool enableRundownProvider = true) { Logger.logger.Log("==TEST STARTING=="); var test = new IpcTraceTest(expectedEventCounts, eventGeneratingAction, providers, circularBufferMB, optionalTraceValidator); try { - var ret = test.Validate(); + var ret = test.Validate(enableRundownProvider); if (ret == 100) Logger.logger.Log("==TEST FINISHED: PASSED!=="); else diff --git a/src/tests/tracing/eventpipe/providervalidation/providervalidation.cs b/src/tests/tracing/eventpipe/providervalidation/providervalidation.cs index 9b509c723e9fa..2da95c1523960 100644 --- a/src/tests/tracing/eventpipe/providervalidation/providervalidation.cs +++ b/src/tests/tracing/eventpipe/providervalidation/providervalidation.cs @@ -44,29 +44,19 @@ public static int Main() private static Dictionary _expectedEventCounts = new Dictionary() { -#if EnableNativeEventPipe - { "MyEventSource", 1 }, - { "Microsoft-DotNETCore-EventPipe", 1} -#else { "MyEventSource", new ExpectedEventCount(100_000, 0.30f) }, { "Microsoft-Windows-DotNETRuntimeRundown", -1 }, { "Microsoft-DotNETCore-SampleProfiler", -1 } -#endif }; private static Action _eventGeneratingAction = () => { -#if EnableNativeEventPipe - Logger.logger.Log($"Firing an event..."); - MyEventSource.Log.MyEvent(); -#else for (int i = 0; i < 100_000; i++) { if (i % 10_000 == 0) Logger.logger.Log($"Fired MyEvent {i:N0}/100,000 times..."); MyEventSource.Log.MyEvent(); } -#endif }; } } diff --git a/src/tests/tracing/eventpipe/providervalidation/providervalidation.csproj b/src/tests/tracing/eventpipe/providervalidation/providervalidation.csproj index 69af1e14f75ce..8a67dfd70a8fc 100644 --- a/src/tests/tracing/eventpipe/providervalidation/providervalidation.csproj +++ b/src/tests/tracing/eventpipe/providervalidation/providervalidation.csproj @@ -6,8 +6,6 @@ true true true - diff --git a/src/tests/tracing/eventpipe/simpleprovidervalidation/Simpleprovidervalidation.cs b/src/tests/tracing/eventpipe/simpleprovidervalidation/Simpleprovidervalidation.cs new file mode 100644 index 0000000000000..b6577fc05bdac --- /dev/null +++ b/src/tests/tracing/eventpipe/simpleprovidervalidation/Simpleprovidervalidation.cs @@ -0,0 +1,57 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Diagnostics.Tracing; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using System.Collections.Generic; +using Microsoft.Diagnostics.Tracing; +using Tracing.Tests.Common; +using Microsoft.Diagnostics.NETCore.Client; + +namespace Tracing.Tests.SimpleProviderValidation +{ + public sealed class MyEventSource : EventSource + { + private MyEventSource() {} + public static MyEventSource Log = new MyEventSource(); + public void MyEvent() { WriteEvent(1, "MyEvent"); } + } + + public class ProviderValidation + { + public static int Main() + { + // This test validates that the rundown events are present + // and that providers turned on that generate events are being written to + // the stream. + + var providers = new List() + { + new EventPipeProvider("MyEventSource", EventLevel.Verbose), + new EventPipeProvider("Microsoft-DotNETCore-SampleProfiler", EventLevel.Verbose) + }; + + var ret = IpcTraceTest.RunAndValidateEventCounts(_expectedEventCounts, _eventGeneratingAction, providers, 1024, enableRundownProvider:false); + if (ret < 0) + return ret; + else + return 100; + } + + private static Dictionary _expectedEventCounts = new Dictionary() + { + { "MyEventSource", 1 }, + { "Microsoft-DotNETCore-EventPipe", 1} + }; + + private static Action _eventGeneratingAction = () => + { + Logger.logger.Log($"Firing an event..."); + MyEventSource.Log.MyEvent(); + }; + } +} diff --git a/src/tests/tracing/eventpipe/simpleprovidervalidation/simpleprovidervalidation.csproj b/src/tests/tracing/eventpipe/simpleprovidervalidation/simpleprovidervalidation.csproj new file mode 100644 index 0000000000000..34d588f3c2dd1 --- /dev/null +++ b/src/tests/tracing/eventpipe/simpleprovidervalidation/simpleprovidervalidation.csproj @@ -0,0 +1,17 @@ + + + .NETCoreApp + exe + true + true + true + true + true + true + + + + + + + From c55e32f4466df88195df16b46f2aa5a652b04b3b Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Thu, 2 Feb 2023 08:48:31 -0800 Subject: [PATCH 26/32] Moving NativeAOT headers away from EventPipe common code --- .../nativeaot/Runtime/EmptyContainers.h | 13 +- .../nativeaot/Runtime/EmptyContainers2.h | 22 +- .../Runtime/EnabledEventPipeInterface.cpp | 5 + .../Runtime/disabledeventpipeinternal.cpp | 6 + .../nativeaot/Runtime/eventpipe/ds-rt-aot.h | 36 +- .../nativeaot/Runtime/eventpipe/ep-rt-aot.cpp | 444 ++++++++++++++++++ .../nativeaot/Runtime/eventpipe/ep-rt-aot.h | 390 +++++++-------- .../Runtime/eventpipe/ep-rt-types-aot.h | 1 - .../nativeaot/Runtime/eventpipeadapter.h | 7 + .../nativeaot/Runtime/eventpipeinternal.cpp | 6 + 10 files changed, 701 insertions(+), 229 deletions(-) diff --git a/src/coreclr/nativeaot/Runtime/EmptyContainers.h b/src/coreclr/nativeaot/Runtime/EmptyContainers.h index e317309c55bf7..f96af50e98bd3 100644 --- a/src/coreclr/nativeaot/Runtime/EmptyContainers.h +++ b/src/coreclr/nativeaot/Runtime/EmptyContainers.h @@ -10,6 +10,7 @@ // Hence initially, the bare boned implementation focus is on unblocking HW/Simple Trace bring up #include "EmptyContainers2.h" +#include "rhassert.h" struct SLink_EP { @@ -143,7 +144,7 @@ class SList_EP void InsertHead(T *pObj) { - PalDebugBreak(); + //PalDebugBreak(); } @@ -181,7 +182,7 @@ class SList_EP T * operator->() const { - PalDebugBreak(); + //PalDebugBreak(); return m_cur; } @@ -232,13 +233,13 @@ struct SListElem_EP ElemT const & operator*() const { - PalDebugBreak(); + //PalDebugBreak(); return m_Value; } ElemT & operator*() { - PalDebugBreak(); + //PalDebugBreak(); return m_Value; } @@ -284,8 +285,8 @@ class CQuickArrayList_EP bool PushNoThrow(const T & value) { - if(m_curSize >= maxSize) - PalDebugBreak(); + // if(m_curSize >= maxSize) + // PalDebugBreak(); m_array[m_curSize++] = value; return true; } diff --git a/src/coreclr/nativeaot/Runtime/EmptyContainers2.h b/src/coreclr/nativeaot/Runtime/EmptyContainers2.h index f045afc4d36e6..44036c21cd0ef 100644 --- a/src/coreclr/nativeaot/Runtime/EmptyContainers2.h +++ b/src/coreclr/nativeaot/Runtime/EmptyContainers2.h @@ -18,9 +18,7 @@ class DefaultSHashTraits_EP public: typedef COUNT_T count_t; typedef ELEMENT element_t; - typedef DPTR(element_t) PTR_element_t; // by default SHash is DAC-aware. For RS - // only SHash use NonDacAwareSHashTraits - // (which typedefs element_t* PTR_element_t) + typedef element_t* PTR_element_t; static const count_t s_growth_factor_numerator = 3; static const count_t s_growth_factor_denominator = 2; @@ -37,7 +35,7 @@ class DefaultSHashTraits_EP static bool IsNull(const ELEMENT &e) { return e == (const ELEMENT) 0; } static bool IsDeleted(const ELEMENT &e) { - PalDebugBreak(); + //PalDebugBreak(); return false; //return e == (const ELEMENT) -1; } @@ -133,8 +131,8 @@ class SHash_EP : public TRAITS bool Reallocate(count_t newTableSize) { - ASSERT(newTableSize >= - (count_t) (GetCount() * TRAITS::s_density_factor_denominator / TRAITS::s_density_factor_numerator)); + // ASSERT(newTableSize >= + // (count_t) (GetCount() * TRAITS::s_density_factor_denominator / TRAITS::s_density_factor_numerator)); // Allocation size must be a prime number. This is necessary so that hashes uniformly // distribute to all indices, and so that chaining will visit all indices in the hash table. @@ -317,12 +315,12 @@ class SHash_EP : public TRAITS bool AddNoThrow(const element_t &element) { - PalDebugBreak(); + //PalDebugBreak(); return false; } bool AddOrReplaceNoThrow(const element_t &element) { - PalDebugBreak(); + //PalDebugBreak(); return false; } @@ -333,13 +331,13 @@ class SHash_EP : public TRAITS void Remove(key_t key) { - PalDebugBreak(); + //PalDebugBreak(); } // Remove the specific element. void Remove(Iterator& i) { - PalDebugBreak(); + //PalDebugBreak(); } void RemoveAll() { @@ -535,13 +533,13 @@ class MapSHashTraits_EP : public DefaultSHashTraits_EP< KeyValuePair_EP #undef DS_LOG_ALWAYS_0 -#define DS_LOG_ALWAYS_0(msg) STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_ALWAYS, msg "\n") +#define DS_LOG_ALWAYS_0(msg) do {} while (0) #undef DS_LOG_ALWAYS_1 -#define DS_LOG_ALWAYS_1(msg, data1) STRESS_LOG1(LF_DIAGNOSTICS_PORT, LL_ALWAYS, msg "\n", data1) +#define DS_LOG_ALWAYS_1(msg, data1) do {} while (0) #undef DS_LOG_ALWAYS_2 -#define DS_LOG_ALWAYS_2(msg, data1, data2) STRESS_LOG2(LF_DIAGNOSTICS_PORT, LL_ALWAYS, msg "\n", data1, data2) +#define DS_LOG_ALWAYS_2(msg, data1, data2) do {} while (0) #undef DS_LOG_INFO_0 -#define DS_LOG_INFO_0(msg) STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_INFO10, msg "\n") +#define DS_LOG_INFO_0(msg) do {} while (0) #undef DS_LOG_INFO_1 -#define DS_LOG_INFO_1(msg, data1) STRESS_LOG1(LF_DIAGNOSTICS_PORT, LL_INFO10, msg "\n", data1) +#define DS_LOG_INFO_1(msg, data1) do {} while (0) #undef DS_LOG_INFO_2 -#define DS_LOG_INFO_2(msg, data1, data2) STRESS_LOG2(LF_DIAGNOSTICS_PORT, LL_INFO10, msg "\n", data1, data2) +#define DS_LOG_INFO_2(msg, data1, data2) do {} while (0) #undef DS_LOG_ERROR_0 -#define DS_LOG_ERROR_0(msg) STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_ERROR, msg "\n") +#define DS_LOG_ERROR_0(msg) do {} while (0) #undef DS_LOG_ERROR_1 -#define DS_LOG_ERROR_1(msg, data1) STRESS_LOG1(LF_DIAGNOSTICS_PORT, LL_ERROR, msg "\n", data1) +#define DS_LOG_ERROR_1(msg, data1) do {} while (0) #undef DS_LOG_ERROR_2 -#define DS_LOG_ERROR_2(msg, data1, data2) STRESS_LOG2(LF_DIAGNOSTICS_PORT, LL_ERROR, msg "\n", data1, data2) +#define DS_LOG_ERROR_2(msg, data1, data2) do {} while (0) #undef DS_LOG_WARNING_0 -#define DS_LOG_WARNING_0(msg) STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_WARNING, msg "\n") +#define DS_LOG_WARNING_0(msg) do {} while (0) #undef DS_LOG_WARNING_1 -#define DS_LOG_WARNING_1(msg, data1) STRESS_LOG1(LF_DIAGNOSTICS_PORT, LL_WARNING, msg "\n", data1) +#define DS_LOG_WARNING_1(msg, data1) do {} while (0) #undef DS_LOG_WARNING_2 -#define DS_LOG_WARNING_2(msg, data1, data2) STRESS_LOG2(LF_DIAGNOSTICS_PORT, LL_WARNING, msg "\n", data1, data2) +#define DS_LOG_WARNING_2(msg, data1, data2) do {} while (0) #undef DS_LOG_DEBUG_0 -#define DS_LOG_DEBUG_0(msg) STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_INFO1000, msg "\n") +#define DS_LOG_DEBUG_0(msg) do {} while (0) #undef DS_LOG_DEBUG_1 -#define DS_LOG_DEBUG_1(msg, data1) STRESS_LOG1(LF_DIAGNOSTICS_PORT, LL_INFO1000, msg "\n", data1) +#define DS_LOG_DEBUG_1(msg, data1) do {} while (0) #undef DS_LOG_DEBUG_2 -#define DS_LOG_DEBUG_2(msg, data1, data2) STRESS_LOG2(LF_DIAGNOSTICS_PORT, LL_INFO1000, msg "\n", data1, data2) +#define DS_LOG_DEBUG_2(msg, data1, data2) do {} while (0) #undef DS_ENTER_BLOCKING_PAL_SECTION #define DS_ENTER_BLOCKING_PAL_SECTION @@ -184,7 +184,7 @@ ds_rt_generate_core_dump ( uint32_t flags = ds_generate_core_dump_command_payload_get_flags(payload); // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Generate an exception dump - PalDebugBreak(); + // PalDebugBreak(); return 0; } @@ -295,7 +295,7 @@ uint32_t ds_rt_set_environment_variable (const ep_char16_t *name, const ep_char16_t *value) { // return SetEnvironmentVariableW(reinterpret_cast(name), reinterpret_cast(value)) ? S_OK : HRESULT_FROM_WIN32(GetLastError()); - PalDebugBreak(); + // PalDebugBreak(); return 0xffff; } @@ -312,7 +312,7 @@ ds_rt_server_log_pause_message (void) const char diagPortsName[] = "DOTNET_DiagnosticPorts"; // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Cannot find nocache versions of RhConfig - PalDebugBreak(); + // PalDebugBreak(); } #endif /* ENABLE_PERFTRACING */ diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp index 389fef29a8d1b..ad1951fc100aa 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp @@ -6,6 +6,17 @@ #include #include +// The regdisplay.h, StackFrameIterator.h, and thread.h includes are present only to access the Thread +// class and can be removed if it turns out that the required ep_rt_thread_handle_t can be +// implemented in some manner that doesn't rely on the Thread class. + +#include "gcenv.h" +#include "regdisplay.h" +#include "StackFrameIterator.h" +#include "thread.h" +#include "holder.h" +#include "SpinLock.h" + ep_rt_lock_handle_t _ep_rt_aot_config_lock_handle; CrstStatic _ep_rt_aot_config_lock; @@ -55,4 +66,437 @@ ep_rt_aot_sample_profiler_write_sampling_event_for_threads ( { } +const ep_char8_t * +ep_rt_aot_entrypoint_assembly_name_get_utf8 (void) +{ + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase + // TODO: Implement EventPipe assembly name - return filename in nativeaot? + PalDebugBreak(); + + // fallback to the empty string if we can't get assembly info, e.g., if the runtime is + // suspended before an assembly is loaded. + return reinterpret_cast(""); +} + +uint32_t +ep_rt_aot_atomic_inc_uint32_t (volatile uint32_t *value) +{ + STATIC_CONTRACT_NOTHROW; + return static_cast(PalInterlockedIncrement ((volatile int32_t *)(value))); +} + +uint32_t +ep_rt_aot_atomic_dec_uint32_t (volatile uint32_t *value) +{ + STATIC_CONTRACT_NOTHROW; + return static_cast(PalInterlockedDecrement ((volatile int32_t *)(value))); +} + +int32_t +ep_rt_aot_atomic_inc_int32_t (volatile int32_t *value) +{ + STATIC_CONTRACT_NOTHROW; + return static_cast(PalInterlockedIncrement (value)); +} + +int32_t +ep_rt_aot_atomic_dec_int32_t (volatile int32_t *value) +{ + STATIC_CONTRACT_NOTHROW; + return static_cast(PalInterlockedDecrement (value)); +} + +int64_t +ep_rt_aot_atomic_inc_int64_t (volatile int64_t *value) +{ + STATIC_CONTRACT_NOTHROW; + + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase + // TODO: Consider replacing with a new PalInterlockedIncrement64 service + int64_t currentValue; + do { + currentValue = *value; + } while (currentValue != PalInterlockedCompareExchange64(value, (currentValue + 1), currentValue)); + + // The current value has been atomically replaced with the incremented value. + return (currentValue + 1); +} + +int64_t +ep_rt_aot_atomic_dec_int64_t (volatile int64_t *value) { + STATIC_CONTRACT_NOTHROW; + + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase + // TODO: Consider replacing with a new PalInterlockedDecrement64 service + int64_t currentValue; + do { + currentValue = *value; + } while (currentValue != PalInterlockedCompareExchange64(value, (currentValue - 1), currentValue)); + + // The current value has been atomically replaced with the decremented value. + return (currentValue - 1); +} + +size_t +ep_rt_aot_atomic_compare_exchange_size_t (volatile size_t *target, size_t expected, size_t value) { + STATIC_CONTRACT_NOTHROW; +#ifdef HOST_64BIT + return static_cast(PalInterlockedCompareExchange64 ((volatile int64_t *)target, (int64_t)value, (int64_t)expected)); +#else + return static_cast(PalInterlockedCompareExchange ((volatile int32_t *)target, (int32_t)value, (int32_t)expected)); +#endif +} + +ep_char8_t * +ep_rt_aot_atomic_compare_exchange_utf8_string (ep_char8_t *volatile *target, ep_char8_t *expected, ep_char8_t *value) { + STATIC_CONTRACT_NOTHROW; + return static_cast(PalInterlockedCompareExchangePointer ((void *volatile *)target, value, expected)); +} + + +void +ep_rt_aot_wait_event_alloc ( + ep_rt_wait_event_handle_t *wait_event, + bool manual, + bool initial) +{ + STATIC_CONTRACT_NOTHROW; + + EP_ASSERT (wait_event != NULL); + EP_ASSERT (wait_event->event == NULL); + + wait_event->event = new (nothrow) CLREventStatic (); + if (wait_event->event) { + // NativeAOT has the NoThrow versions + if (manual) + wait_event->event->CreateManualEventNoThrow (initial); + else + wait_event->event->CreateAutoEventNoThrow (initial); + } +} + +void +ep_rt_aot_wait_event_free (ep_rt_wait_event_handle_t *wait_event) +{ + STATIC_CONTRACT_NOTHROW; + + if (wait_event != NULL && wait_event->event != NULL) { + wait_event->event->CloseEvent (); + delete wait_event->event; + wait_event->event = NULL; + } +} + +bool +ep_rt_aot_wait_event_set (ep_rt_wait_event_handle_t *wait_event) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (wait_event != NULL && wait_event->event != NULL); + + return wait_event->event->Set (); +} + +int32_t +ep_rt_aot_wait_event_wait ( + ep_rt_wait_event_handle_t *wait_event, + uint32_t timeout, + bool alertable) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (wait_event != NULL && wait_event->event != NULL); + + return wait_event->event->Wait (timeout, alertable); +} + +bool +ep_rt_aot_wait_event_is_valid (ep_rt_wait_event_handle_t *wait_event) +{ + STATIC_CONTRACT_NOTHROW; + + if (wait_event == NULL || wait_event->event == NULL) + return false; + + return wait_event->event->IsValid (); +} + +/* + * Misc. + */ + +int +ep_rt_aot_get_last_error (void) +{ + STATIC_CONTRACT_NOTHROW; + return PalGetLastError(); +} + +bool +ep_rt_aot_thread_create ( + void *thread_func, + void *params, + EventPipeThreadType thread_type, + void *id) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (thread_func != NULL); + + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase + // TODO: Fill in the outgoing id if any callers ever need it + if (id) + *reinterpret_cast(id) = 0xffffffff; + + switch (thread_type) + { + default: + return false; + + case EP_THREAD_TYPE_SERVER: + // Match CoreCLR and hardcode a null thread context in this case. + return PalStartEventPipeHelperThread(reinterpret_cast(thread_func), NULL); + + case EP_THREAD_TYPE_SESSION: + case EP_THREAD_TYPE_SAMPLING: + ep_rt_thread_params_t* thread_params = new (nothrow) ep_rt_thread_params_t (); + if (!thread_params) + return false; + + thread_params->thread_type = thread_type; + thread_params->thread_func = reinterpret_cast(thread_func); + thread_params->thread_params = params; + if (!PalStartEventPipeHelperThread(reinterpret_cast(ep_rt_thread_aot_start_session_or_sampling_thread), thread_params)) { + delete thread_params; + return false; + } + + return true; + } +} + +void +ep_rt_aot_thread_sleep (uint64_t ns) +{ + STATIC_CONTRACT_NOTHROW; + PalSleep(static_cast(ns/1000000)); +} + +uint32_t +ep_rt_aot_current_process_get_id (void) +{ + STATIC_CONTRACT_NOTHROW; + return static_cast(GetCurrentProcessId ()); +} + +ep_rt_thread_id_t +ep_rt_aot_current_thread_get_id (void) +{ + STATIC_CONTRACT_NOTHROW; + +#ifdef TARGET_UNIX + // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase + // TODO: AOT doesn't have PAL_GetCurrentOSThreadId, as CoreCLR does. + // PalDebugBreak(); + return static_cast(0); +#else + return static_cast(::GetCurrentThreadId ()); +#endif +} + +int64_t +ep_rt_aot_perf_counter_query (void) +{ + STATIC_CONTRACT_NOTHROW; + return (int64_t)PalQueryPerformanceCounter(); +} + +int64_t +ep_rt_aot_perf_frequency_query (void) +{ + STATIC_CONTRACT_NOTHROW; + return (int64_t)PalQueryPerformanceFrequency(); +} + +int64_t +ep_rt_aot_system_timestamp_get (void) +{ + STATIC_CONTRACT_NOTHROW; + + FILETIME value; + GetSystemTimeAsFileTime (&value); + return static_cast(((static_cast(value.dwHighDateTime)) << 32) | static_cast(value.dwLowDateTime)); +} + +uint8_t * +ep_rt_aot_valloc0 (size_t buffer_size) +{ + STATIC_CONTRACT_NOTHROW; + return reinterpret_cast(PalVirtualAlloc (NULL, buffer_size, MEM_COMMIT, PAGE_READWRITE)); +} + +void +ep_rt_aot_vfree ( + uint8_t *buffer, + size_t buffer_size) +{ + STATIC_CONTRACT_NOTHROW; + + if (buffer) + PalVirtualFree (buffer, 0, MEM_RELEASE); +} + +void +ep_rt_aot_spin_lock_alloc (ep_rt_spin_lock_handle_t *spin_lock) +{ + STATIC_CONTRACT_NOTHROW; + + spin_lock->lock = new (nothrow) SpinLock (); +} + +void +ep_rt_aot_spin_lock_free (ep_rt_spin_lock_handle_t *spin_lock) +{ + STATIC_CONTRACT_NOTHROW; + + if (spin_lock && spin_lock->lock) { + delete spin_lock->lock; + spin_lock->lock = NULL; + } +} + +size_t +ep_rt_aot_utf16_string_len (const ep_char16_t *str) +{ + STATIC_CONTRACT_NOTHROW; + EP_ASSERT (str != NULL); + + return wcslen (reinterpret_cast(str)); +} + +uint32_t +ep_rt_aot_volatile_load_uint32_t (const volatile uint32_t *ptr) +{ + STATIC_CONTRACT_NOTHROW; + return VolatileLoad ((const uint32_t *)ptr); +} + +uint32_t +ep_rt_aot_volatile_load_uint32_t_without_barrier (const volatile uint32_t *ptr) +{ + STATIC_CONTRACT_NOTHROW; + return VolatileLoadWithoutBarrier ((const uint32_t *)ptr); +} + +void +ep_rt_aot_volatile_store_uint32_t ( + volatile uint32_t *ptr, + uint32_t value) +{ + STATIC_CONTRACT_NOTHROW; + VolatileStore ((uint32_t *)ptr, value); +} + +void +ep_rt_aot_volatile_store_uint32_t_without_barrier ( + volatile uint32_t *ptr, + uint32_t value) +{ + STATIC_CONTRACT_NOTHROW; + VolatileStoreWithoutBarrier((uint32_t *)ptr, value); +} + +uint64_t +ep_rt_aot_volatile_load_uint64_t (const volatile uint64_t *ptr) +{ + STATIC_CONTRACT_NOTHROW; + return VolatileLoad ((const uint64_t *)ptr); +} + +uint64_t +ep_rt_aot_volatile_load_uint64_t_without_barrier (const volatile uint64_t *ptr) +{ + STATIC_CONTRACT_NOTHROW; + return VolatileLoadWithoutBarrier ((const uint64_t *)ptr); +} + +void +ep_rt_aot_volatile_store_uint64_t ( + volatile uint64_t *ptr, + uint64_t value) +{ + STATIC_CONTRACT_NOTHROW; + VolatileStore ((uint64_t *)ptr, value); +} + +void +ep_rt_aot_volatile_store_uint64_t_without_barrier ( + volatile uint64_t *ptr, + uint64_t value) +{ + STATIC_CONTRACT_NOTHROW; + VolatileStoreWithoutBarrier ((uint64_t *)ptr, value); +} + +int64_t +ep_rt_aot_volatile_load_int64_t (const volatile int64_t *ptr) +{ + STATIC_CONTRACT_NOTHROW; + return VolatileLoad ((int64_t *)ptr); +} + +int64_t +ep_rt_aot_volatile_load_int64_t_without_barrier (const volatile int64_t *ptr) +{ + STATIC_CONTRACT_NOTHROW; + return VolatileLoadWithoutBarrier ((int64_t *)ptr); +} + +void +ep_rt_aot_volatile_store_int64_t ( + volatile int64_t *ptr, + int64_t value) +{ + STATIC_CONTRACT_NOTHROW; + VolatileStore ((int64_t *)ptr, value); +} + +void +ep_rt_aot_volatile_store_int64_t_without_barrier ( + volatile int64_t *ptr, + int64_t value) +{ + STATIC_CONTRACT_NOTHROW; + VolatileStoreWithoutBarrier ((int64_t *)ptr, value); +} + +void * +ep_rt_aot_volatile_load_ptr (volatile void **ptr) +{ + STATIC_CONTRACT_NOTHROW; + return VolatileLoad ((void **)ptr); +} + +void * +ep_rt_aot_volatile_load_ptr_without_barrier (volatile void **ptr) +{ + STATIC_CONTRACT_NOTHROW; + return VolatileLoadWithoutBarrier ((void **)ptr); +} + +void +ep_rt_aot_volatile_store_ptr ( + volatile void **ptr, + void *value) +{ + STATIC_CONTRACT_NOTHROW; + VolatileStore ((void **)ptr, value); +} + +void +ep_rt_aot_volatile_store_ptr_without_barrier ( + volatile void **ptr, + void *value) +{ + STATIC_CONTRACT_NOTHROW; + VolatileStoreWithoutBarrier ((void **)ptr, value); +} + #endif /* ENABLE_PERFTRACING */ diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h index 7831f0dc27e0e..2b9f7bd0ab65d 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h @@ -11,19 +11,8 @@ #include #include -// The regdisplay.h, StackFrameIterator.h, and thread.h includes are present only to access the Thread -// class and can be removed if it turns out that the required ep_rt_thread_handle_t can be -// implemented in some manner that doesn't rely on the Thread class. - -#include "gcenv.h" -#include "regdisplay.h" -#include "StackFrameIterator.h" -#include "thread.h" -#include "holder.h" -#include "SpinLock.h" -#ifdef _INC_WINDOWS -#include -#endif +#include "rhassert.h" + #define STATIC_CONTRACT_NOTHROW #undef EP_INFINITE_WAIT @@ -39,7 +28,7 @@ #define EP_ALWAYS_INLINE FORCEINLINE #undef EP_NEVER_INLINE -#define EP_NEVER_INLINE NOINLINE +#define EP_NEVER_INLINE #undef EP_ALIGN_UP #define EP_ALIGN_UP(val,align) _rt_aot_align_up(val,align) @@ -1143,17 +1132,12 @@ ep_rt_aot_config_lock_get (void) static inline const ep_char8_t * -ep_rt_entrypoint_assembly_name_get_utf8 (void) +ep_rt_entrypoint_assembly_name_get_utf8 (void) { STATIC_CONTRACT_NOTHROW; - // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase - // TODO: Implement EventPipe assembly name - return filename in nativeaot? - PalDebugBreak(); - - // fallback to the empty string if we can't get assembly info, e.g., if the runtime is - // suspended before an assembly is loaded. - return reinterpret_cast(""); + extern const ep_char8_t * ep_rt_aot_entrypoint_assembly_name_get_utf8 (void); + return ep_rt_aot_entrypoint_assembly_name_get_utf8(); } static @@ -1171,7 +1155,7 @@ ep_rt_runtime_version_get_utf8 (void) { */ static -EP_ALWAYS_INLINE +inline uint16_t ep_rt_val_uint16_t (uint16_t value) { @@ -1179,7 +1163,7 @@ ep_rt_val_uint16_t (uint16_t value) } static -EP_ALWAYS_INLINE +inline uint32_t ep_rt_val_uint32_t (uint32_t value) { @@ -1187,7 +1171,7 @@ ep_rt_val_uint32_t (uint32_t value) } static -EP_ALWAYS_INLINE +inline uint64_t ep_rt_val_uint64_t (uint64_t value) { @@ -1195,7 +1179,7 @@ ep_rt_val_uint64_t (uint64_t value) } static -EP_ALWAYS_INLINE +inline int16_t ep_rt_val_int16_t (int16_t value) { @@ -1203,7 +1187,7 @@ ep_rt_val_int16_t (int16_t value) } static -EP_ALWAYS_INLINE +inline int32_t ep_rt_val_int32_t (int32_t value) { @@ -1211,7 +1195,7 @@ ep_rt_val_int32_t (int32_t value) } static -EP_ALWAYS_INLINE +inline int64_t ep_rt_val_int64_t (int64_t value) { @@ -1219,7 +1203,7 @@ ep_rt_val_int64_t (int64_t value) } static -EP_ALWAYS_INLINE +inline uintptr_t ep_rt_val_uintptr_t (uintptr_t value) { @@ -1236,7 +1220,8 @@ uint32_t ep_rt_atomic_inc_uint32_t (volatile uint32_t *value) { STATIC_CONTRACT_NOTHROW; - return static_cast(PalInterlockedIncrement ((volatile int32_t *)(value))); + extern uint32_t ep_rt_aot_atomic_inc_uint32_t (volatile uint32_t *value); + return ep_rt_aot_atomic_inc_uint32_t (value); } static @@ -1245,7 +1230,8 @@ uint32_t ep_rt_atomic_dec_uint32_t (volatile uint32_t *value) { STATIC_CONTRACT_NOTHROW; - return static_cast(PalInterlockedDecrement ((volatile int32_t *)(value))); + extern uint32_t ep_rt_aot_atomic_dec_uint32_t (volatile uint32_t *value); + return ep_rt_aot_atomic_dec_uint32_t (value); } static @@ -1254,7 +1240,9 @@ int32_t ep_rt_atomic_inc_int32_t (volatile int32_t *value) { STATIC_CONTRACT_NOTHROW; - return static_cast(PalInterlockedIncrement (value)); + extern int32_t ep_rt_aot_atomic_inc_int32_t (volatile int32_t *value); + + return ep_rt_aot_atomic_inc_int32_t (value); } static @@ -1263,7 +1251,8 @@ int32_t ep_rt_atomic_dec_int32_t (volatile int32_t *value) { STATIC_CONTRACT_NOTHROW; - return static_cast(PalInterlockedDecrement (value)); + extern int32_t ep_rt_aot_atomic_dec_int32_t (volatile int32_t *value); + return ep_rt_aot_atomic_dec_int32_t (value); } static @@ -1273,52 +1262,39 @@ ep_rt_atomic_inc_int64_t (volatile int64_t *value) { STATIC_CONTRACT_NOTHROW; - // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase - // TODO: Consider replacing with a new PalInterlockedIncrement64 service - int64_t currentValue; - do { - currentValue = *value; - } while (currentValue != PalInterlockedCompareExchange64(value, (currentValue + 1), currentValue)); - - // The current value has been atomically replaced with the incremented value. - return (currentValue + 1); + extern int64_t ep_rt_aot_atomic_inc_int64_t (volatile int64_t *value); + return ep_rt_aot_atomic_inc_int64_t (value); } static inline int64_t -ep_rt_atomic_dec_int64_t (volatile int64_t *value) { +ep_rt_atomic_dec_int64_t (volatile int64_t *value) +{ STATIC_CONTRACT_NOTHROW; - // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase - // TODO: Consider replacing with a new PalInterlockedDecrement64 service - int64_t currentValue; - do { - currentValue = *value; - } while (currentValue != PalInterlockedCompareExchange64(value, (currentValue - 1), currentValue)); - - // The current value has been atomically replaced with the decremented value. - return (currentValue - 1); + extern int64_t ep_rt_aot_atomic_dec_int64_t (volatile int64_t *value); + return ep_rt_aot_atomic_dec_int64_t (value); } static inline size_t -ep_rt_atomic_compare_exchange_size_t (volatile size_t *target, size_t expected, size_t value) { +ep_rt_atomic_compare_exchange_size_t (volatile size_t *target, size_t expected, size_t value) +{ STATIC_CONTRACT_NOTHROW; -#ifdef HOST_64BIT - return static_cast(PalInterlockedCompareExchange64 ((volatile int64_t *)target, (int64_t)value, (int64_t)expected)); -#else - return static_cast(PalInterlockedCompareExchange ((volatile int32_t *)target, (int32_t)value, (int32_t)expected)); -#endif + extern size_t ep_rt_aot_atomic_compare_exchange_size_t (volatile size_t *target, size_t expected, size_t value); + return ep_rt_aot_atomic_compare_exchange_size_t (target, expected, value); } static inline ep_char8_t * -ep_rt_atomic_compare_exchange_utf8_string (ep_char8_t *volatile *target, ep_char8_t *expected, ep_char8_t *value) { +ep_rt_atomic_compare_exchange_utf8_string (ep_char8_t *volatile *target, ep_char8_t *expected, ep_char8_t *value) +{ STATIC_CONTRACT_NOTHROW; - return static_cast(PalInterlockedCompareExchangePointer ((void *volatile *)target, value, expected)); + extern ep_char8_t * ep_rt_aot_atomic_compare_exchange_utf8_string (ep_char8_t *volatile *target, ep_char8_t *expected, ep_char8_t *value); + return ep_rt_aot_atomic_compare_exchange_utf8_string (target, expected, value); } /* @@ -1421,7 +1397,7 @@ ep_rt_method_get_simple_assembly_name ( // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Design MethodDesc and method name services if/when needed - PalDebugBreak(); + //PalDebugBreak(); return false; @@ -1436,7 +1412,7 @@ ep_rt_method_get_full_name ( { // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Design MethodDesc and method name services if/when needed - PalDebugBreak(); + //PalDebugBreak(); return false; } @@ -1610,7 +1586,7 @@ ep_rt_config_value_get_config (void) // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: EventPipe Configuration values - RhConfig? // (CLRConfig::INTERNAL_EventPipeConfig) - PalDebugBreak(); + // PalDebugBreak(); return nullptr; // return ep_rt_utf16_to_utf8_string (reinterpret_cast(value.GetValue ()), -1); } @@ -1624,7 +1600,7 @@ ep_rt_config_value_get_output_path (void) // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: EventPipe Configuration values - RhConfig? // (CLRConfig::INTERNAL_EventPipeOutputPath) - PalDebugBreak(); + //PalDebugBreak(); return nullptr; } @@ -1637,7 +1613,7 @@ ep_rt_config_value_get_circular_mb (void) // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: EventPipe Configuration values - RhConfig? // (CLRConfig::INTERNAL_EventPipeCircularMB) - PalDebugBreak(); + //PalDebugBreak(); return 0; } @@ -1650,7 +1626,7 @@ ep_rt_config_value_get_output_streaming (void) // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: EventPipe Configuration values - RhConfig? // (CLRConfig::INTERNAL_EventPipeOutputStreaming) - PalDebugBreak(); + //PalDebugBreak(); return false; } @@ -1783,17 +1759,11 @@ ep_rt_wait_event_alloc ( { STATIC_CONTRACT_NOTHROW; - EP_ASSERT (wait_event != NULL); - EP_ASSERT (wait_event->event == NULL); - - wait_event->event = new (nothrow) CLREventStatic (); - if (wait_event->event) { - // NativeAOT has the NoThrow versions - if (manual) - wait_event->event->CreateManualEventNoThrow (initial); - else - wait_event->event->CreateAutoEventNoThrow (initial); - } + extern void ep_rt_aot_wait_event_alloc ( + ep_rt_wait_event_handle_t *wait_event, + bool manual, + bool initial); + ep_rt_aot_wait_event_alloc(wait_event, manual, initial); } static @@ -1802,12 +1772,8 @@ void ep_rt_wait_event_free (ep_rt_wait_event_handle_t *wait_event) { STATIC_CONTRACT_NOTHROW; - - if (wait_event != NULL && wait_event->event != NULL) { - wait_event->event->CloseEvent (); - delete wait_event->event; - wait_event->event = NULL; - } + extern void ep_rt_aot_wait_event_free (ep_rt_wait_event_handle_t *wait_event); + ep_rt_aot_wait_event_free(wait_event); } static @@ -1816,9 +1782,8 @@ bool ep_rt_wait_event_set (ep_rt_wait_event_handle_t *wait_event) { STATIC_CONTRACT_NOTHROW; - EP_ASSERT (wait_event != NULL && wait_event->event != NULL); - - return wait_event->event->Set (); + extern bool ep_rt_aot_wait_event_set (ep_rt_wait_event_handle_t *wait_event); + return ep_rt_aot_wait_event_set (wait_event); } static @@ -1829,9 +1794,13 @@ ep_rt_wait_event_wait ( bool alertable) { STATIC_CONTRACT_NOTHROW; - EP_ASSERT (wait_event != NULL && wait_event->event != NULL); + extern int32_t +ep_rt_aot_wait_event_wait ( + ep_rt_wait_event_handle_t *wait_event, + uint32_t timeout, + bool alertable); - return wait_event->event->Wait (timeout, alertable); + return ep_rt_aot_wait_event_wait(wait_event, timeout, alertable); } static @@ -1840,11 +1809,11 @@ EventPipeWaitHandle ep_rt_wait_event_get_wait_handle (ep_rt_wait_event_handle_t *wait_event) { STATIC_CONTRACT_NOTHROW; - EP_ASSERT (wait_event != NULL && wait_event->event != NULL); + // EP_ASSERT (wait_event != NULL && wait_event->event != NULL); // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: NativeAOT CLREventStatic doesn't have GetHandleUNHOSTED - PalDebugBreak(); + // PalDebugBreak(); return 0; } @@ -1854,11 +1823,10 @@ bool ep_rt_wait_event_is_valid (ep_rt_wait_event_handle_t *wait_event) { STATIC_CONTRACT_NOTHROW; + extern bool + ep_rt_aot_wait_event_is_valid (ep_rt_wait_event_handle_t *wait_event); - if (wait_event == NULL || wait_event->event == NULL) - return false; - - return wait_event->event->IsValid (); + return ep_rt_aot_wait_event_is_valid (wait_event); } /* @@ -1871,7 +1839,9 @@ int ep_rt_get_last_error (void) { STATIC_CONTRACT_NOTHROW; - return PalGetLastError(); + extern int + ep_rt_aot_get_last_error (void); + return ep_rt_aot_get_last_error (); } static @@ -1946,7 +1916,7 @@ ep_rt_is_running (void) STATIC_CONTRACT_NOTHROW; // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Does NativeAot have the concept of EEStarted - PalDebugBreak(); + // PalDebugBreak(); return false; } @@ -1962,7 +1932,7 @@ ep_rt_execute_rundown (ep_rt_execution_checkpoint_array_t *execution_checkpoints // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: EventPipe Configuration values - RhConfig? // (CLRConfig::INTERNAL_EventPipeCircularMB) - PalDebugBreak(); + // PalDebugBreak(); } /* @@ -2019,39 +1989,14 @@ ep_rt_thread_create ( void *id) { STATIC_CONTRACT_NOTHROW; - EP_ASSERT (thread_func != NULL); - - // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase - // TODO: Fill in the outgoing id if any callers ever need it - if (id) - *reinterpret_cast(id) = 0xffffffff; - - switch (thread_type) - { - default: - return false; - - case EP_THREAD_TYPE_SERVER: - // Match CoreCLR and hardcode a null thread context in this case. - return PalStartEventPipeHelperThread(reinterpret_cast(thread_func), NULL); - - case EP_THREAD_TYPE_SESSION: - case EP_THREAD_TYPE_SAMPLING: - ep_rt_thread_params_t* thread_params = new (nothrow) ep_rt_thread_params_t (); - if (!thread_params) - return false; - - thread_params->thread_type = thread_type; - thread_params->thread_func = reinterpret_cast(thread_func); - thread_params->thread_params = params; - if (!PalStartEventPipeHelperThread(reinterpret_cast(ep_rt_thread_aot_start_session_or_sampling_thread), thread_params)) { - delete thread_params; - return false; - } - - return true; - } + extern bool + ep_rt_aot_thread_create ( + void *thread_func, + void *params, + EventPipeThreadType thread_type, + void *id); + return ep_rt_aot_thread_create(thread_func, params, thread_type, id); } static @@ -2071,7 +2016,9 @@ void ep_rt_thread_sleep (uint64_t ns) { STATIC_CONTRACT_NOTHROW; - PalSleep(static_cast(ns/1000000)); + extern void + ep_rt_aot_thread_sleep (uint64_t ns); + ep_rt_aot_thread_sleep(ns); } static @@ -2080,7 +2027,9 @@ uint32_t ep_rt_current_process_get_id (void) { STATIC_CONTRACT_NOTHROW; - return static_cast(GetCurrentProcessId ()); + extern uint32_t + ep_rt_aot_current_process_get_id (void); + return ep_rt_aot_current_process_get_id(); } static @@ -2096,7 +2045,7 @@ ep_rt_current_processor_get_number (void) // PROCESSOR_NUMBER proc; // GetCurrentProcessorNumberEx (&proc); // return _ep_rt_aot_proc_group_offsets [proc.Group] + proc.Number; - PalDebugBreak(); + // PalDebugBreak(); } #endif return 0xFFFFFFFF; @@ -2113,7 +2062,7 @@ ep_rt_processors_get_count (void) GetSystemInfo (&sys_info); return static_cast(sys_info.dwNumberOfProcessors); #else - PalDebugBreak(); + // PalDebugBreak(); return 0xffff; #endif } @@ -2124,15 +2073,9 @@ ep_rt_thread_id_t ep_rt_current_thread_get_id (void) { STATIC_CONTRACT_NOTHROW; - -#ifdef TARGET_UNIX - // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase - // TODO: AOT doesn't have PAL_GetCurrentOSThreadId, as CoreCLR does. - PalDebugBreak(); - return static_cast(0); -#else - return static_cast(::GetCurrentThreadId ()); -#endif + extern ep_rt_thread_id_t + ep_rt_aot_current_thread_get_id (void); + return ep_rt_aot_current_thread_get_id(); } static @@ -2141,7 +2084,10 @@ int64_t ep_rt_perf_counter_query (void) { STATIC_CONTRACT_NOTHROW; - return (int64_t)PalQueryPerformanceCounter(); + extern int64_t + ep_rt_aot_perf_counter_query (void); + + return ep_rt_aot_perf_counter_query(); } static @@ -2150,7 +2096,10 @@ int64_t ep_rt_perf_frequency_query (void) { STATIC_CONTRACT_NOTHROW; - return (int64_t)PalQueryPerformanceFrequency(); + extern int64_t + ep_rt_aot_perf_frequency_query (void); + + return ep_rt_aot_perf_frequency_query(); } static @@ -2178,7 +2127,7 @@ ep_rt_system_time_get (EventPipeSystemTime *system_time) #else // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Get System time - PalDebugBreak(); + // PalDebugBreak(); #endif } @@ -2189,10 +2138,8 @@ int64_t ep_rt_system_timestamp_get (void) { STATIC_CONTRACT_NOTHROW; - - FILETIME value; - GetSystemTimeAsFileTime (&value); - return static_cast(((static_cast(value.dwHighDateTime)) << 32) | static_cast(value.dwLowDateTime)); + extern int64_t ep_rt_aot_system_timestamp_get (void); + return ep_rt_aot_system_timestamp_get(); } static @@ -2211,7 +2158,7 @@ const ep_char8_t * ep_rt_os_command_line_get (void) { STATIC_CONTRACT_NOTHROW; - EP_UNREACHABLE ("Can not reach here"); + //EP_UNREACHABLE ("Can not reach here"); return NULL; } @@ -2227,7 +2174,7 @@ ep_rt_file_open_write (const ep_char8_t *path) // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Find out the way to open a file in native - PalDebugBreak(); + // PalDebugBreak(); return 0; } @@ -2241,7 +2188,7 @@ ep_rt_file_close (ep_rt_file_handle_t file_handle) // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Find out the way to close a file in native - PalDebugBreak(); + // PalDebugBreak(); return true; } @@ -2259,7 +2206,7 @@ ep_rt_file_write ( // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Find out the way to write to a file in native - PalDebugBreak(); + // PalDebugBreak(); return false; } @@ -2270,7 +2217,10 @@ uint8_t * ep_rt_valloc0 (size_t buffer_size) { STATIC_CONTRACT_NOTHROW; - return reinterpret_cast(PalVirtualAlloc (NULL, buffer_size, MEM_COMMIT, PAGE_READWRITE)); + extern uint8_t * + ep_rt_aot_valloc0 (size_t buffer_size); + + return ep_rt_aot_valloc0(buffer_size); } static @@ -2281,9 +2231,12 @@ ep_rt_vfree ( size_t buffer_size) { STATIC_CONTRACT_NOTHROW; + extern void + ep_rt_aot_vfree ( + uint8_t *buffer, + size_t buffer_size); - if (buffer) - PalVirtualFree (buffer, 0, MEM_RELEASE); + return ep_rt_aot_vfree(buffer, buffer_size); } static @@ -2294,7 +2247,7 @@ ep_rt_temp_path_get ( uint32_t buffer_len) { STATIC_CONTRACT_NOTHROW; - EP_UNREACHABLE ("Can not reach here"); +// EP_UNREACHABLE ("Can not reach here"); return 0; } @@ -2309,7 +2262,7 @@ ep_rt_os_environment_get_utf16 (ep_rt_env_array_utf16_t *env_array) STATIC_CONTRACT_NOTHROW; EP_ASSERT (env_array != NULL); - PalDebugBreak(); + // PalDebugBreak(); } /* @@ -2350,7 +2303,7 @@ ep_rt_lock_requires_lock_held (const ep_rt_lock_handle_t *lock) { STATIC_CONTRACT_NOTHROW; - EP_ASSERT (((ep_rt_lock_handle_t *)lock)->lock->OwnedByCurrentThread ()); + //EP_ASSERT (((ep_rt_lock_handle_t *)lock)->lock->OwnedByCurrentThread ()); } static @@ -2359,7 +2312,7 @@ void ep_rt_lock_requires_lock_not_held (const ep_rt_lock_handle_t *lock) { STATIC_CONTRACT_NOTHROW; - EP_ASSERT (lock->lock == NULL || !((ep_rt_lock_handle_t *)lock)->lock->OwnedByCurrentThread ()); + //EP_ASSERT (lock->lock == NULL || !((ep_rt_lock_handle_t *)lock)->lock->OwnedByCurrentThread ()); } #endif @@ -2372,8 +2325,9 @@ void ep_rt_spin_lock_alloc (ep_rt_spin_lock_handle_t *spin_lock) { STATIC_CONTRACT_NOTHROW; - - spin_lock->lock = new (nothrow) SpinLock (); + extern void + ep_rt_aot_spin_lock_alloc (ep_rt_spin_lock_handle_t *spin_lock); + ep_rt_aot_spin_lock_alloc(spin_lock); } static @@ -2382,11 +2336,9 @@ void ep_rt_spin_lock_free (ep_rt_spin_lock_handle_t *spin_lock) { STATIC_CONTRACT_NOTHROW; - - if (spin_lock && spin_lock->lock) { - delete spin_lock->lock; - spin_lock->lock = NULL; - } + extern void + ep_rt_aot_spin_lock_free (ep_rt_spin_lock_handle_t *spin_lock); + ep_rt_aot_spin_lock_free(spin_lock); } static @@ -2395,7 +2347,7 @@ bool ep_rt_spin_lock_acquire (ep_rt_spin_lock_handle_t *spin_lock) { STATIC_CONTRACT_NOTHROW; - EP_ASSERT (ep_rt_spin_lock_is_valid (spin_lock)); +// EP_ASSERT (ep_rt_spin_lock_is_valid (spin_lock)); // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implement locking (maybe by making the manual Lock and Unlock functions public) @@ -2647,9 +2599,9 @@ size_t ep_rt_utf16_string_len (const ep_char16_t *str) { STATIC_CONTRACT_NOTHROW; - EP_ASSERT (str != NULL); - - return wcslen (reinterpret_cast(str)); + extern size_t + ep_rt_aot_utf16_string_len (const ep_char16_t *str); + return ep_rt_aot_utf16_string_len(str); } static @@ -2711,7 +2663,7 @@ const ep_char8_t * ep_rt_managed_command_line_get (void) { STATIC_CONTRACT_NOTHROW; - EP_UNREACHABLE ("Can not reach here"); + //EP_UNREACHABLE ("Can not reach here"); return NULL; } @@ -2860,7 +2812,7 @@ ep_rt_thread_get_id (ep_rt_thread_handle_t thread_handle) // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implement thread creation/management if needed // return ep_rt_uint64_t_to_thread_id_t (thread_handle->GetOSThreadId64 ()); - PalDebugBreak(); + // PalDebugBreak(); return 0; } @@ -2901,7 +2853,7 @@ ep_rt_thread_get_activity_id_handle (void) // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implement thread creation/management if needed // return GetThread (); - PalDebugBreak(); + // PalDebugBreak(); return NULL; } @@ -2916,7 +2868,7 @@ ep_rt_thread_get_activity_id_cref (ep_rt_thread_activity_id_handle_t activity_id // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implement thread creation/management if needed // return reinterpret_cast(activity_id_handle->GetActivityId ()); - PalDebugBreak(); + // PalDebugBreak(); return NULL; } @@ -2952,7 +2904,7 @@ ep_rt_thread_set_activity_id ( // shipping criteria: no EVENTPIPE-NATIVEAOT-TODO left in the codebase // TODO: Implement thread creation/management if needed // activity_id_handle->SetActivityId (reinterpret_cast(activity_id)); - PalDebugBreak(); + // PalDebugBreak(); } #undef EP_YIELD_WHILE @@ -2975,7 +2927,9 @@ uint32_t ep_rt_volatile_load_uint32_t (const volatile uint32_t *ptr) { STATIC_CONTRACT_NOTHROW; - return VolatileLoad ((const uint32_t *)ptr); + extern uint32_t + ep_rt_aot_volatile_load_uint32_t (const volatile uint32_t *ptr); + return ep_rt_aot_volatile_load_uint32_t(ptr); } static @@ -2984,7 +2938,10 @@ uint32_t ep_rt_volatile_load_uint32_t_without_barrier (const volatile uint32_t *ptr) { STATIC_CONTRACT_NOTHROW; - return VolatileLoadWithoutBarrier ((const uint32_t *)ptr); + extern uint32_t + ep_rt_aot_volatile_load_uint32_t_without_barrier (const volatile uint32_t *ptr); + + return ep_rt_aot_volatile_load_uint32_t_without_barrier(ptr); } static @@ -2995,7 +2952,12 @@ ep_rt_volatile_store_uint32_t ( uint32_t value) { STATIC_CONTRACT_NOTHROW; - VolatileStore ((uint32_t *)ptr, value); + extern void + ep_rt_aot_volatile_store_uint32_t ( + volatile uint32_t *ptr, + uint32_t value); + + ep_rt_aot_volatile_store_uint32_t(ptr, value); } static @@ -3006,7 +2968,12 @@ ep_rt_volatile_store_uint32_t_without_barrier ( uint32_t value) { STATIC_CONTRACT_NOTHROW; - VolatileStoreWithoutBarrier((uint32_t *)ptr, value); + extern void + ep_rt_aot_volatile_store_uint32_t_without_barrier ( + volatile uint32_t *ptr, + uint32_t value); + + ep_rt_aot_volatile_store_uint32_t_without_barrier(ptr, value); } static @@ -3015,7 +2982,10 @@ uint64_t ep_rt_volatile_load_uint64_t (const volatile uint64_t *ptr) { STATIC_CONTRACT_NOTHROW; - return VolatileLoad ((const uint64_t *)ptr); + extern uint64_t + ep_rt_aot_volatile_load_uint64_t (const volatile uint64_t *ptr); + + return ep_rt_aot_volatile_load_uint64_t(ptr); } static @@ -3024,7 +2994,10 @@ uint64_t ep_rt_volatile_load_uint64_t_without_barrier (const volatile uint64_t *ptr) { STATIC_CONTRACT_NOTHROW; - return VolatileLoadWithoutBarrier ((const uint64_t *)ptr); + extern uint64_t + ep_rt_aot_volatile_load_uint64_t_without_barrier (const volatile uint64_t *ptr); + + return ep_rt_aot_volatile_load_uint64_t_without_barrier(ptr); } static @@ -3035,7 +3008,12 @@ ep_rt_volatile_store_uint64_t ( uint64_t value) { STATIC_CONTRACT_NOTHROW; - VolatileStore ((uint64_t *)ptr, value); + extern void + ep_rt_aot_volatile_store_uint64_t ( + volatile uint64_t *ptr, + uint64_t value); + + ep_rt_aot_volatile_store_uint64_t(ptr, value); } static @@ -3046,7 +3024,11 @@ ep_rt_volatile_store_uint64_t_without_barrier ( uint64_t value) { STATIC_CONTRACT_NOTHROW; - VolatileStoreWithoutBarrier ((uint64_t *)ptr, value); + extern void + ep_rt_aot_volatile_store_uint64_t_without_barrier ( + volatile uint64_t *ptr, + uint64_t value); + ep_rt_aot_volatile_store_uint64_t_without_barrier(ptr, value); } static @@ -3055,7 +3037,9 @@ int64_t ep_rt_volatile_load_int64_t (const volatile int64_t *ptr) { STATIC_CONTRACT_NOTHROW; - return VolatileLoad ((int64_t *)ptr); + extern int64_t + ep_rt_aot_volatile_load_int64_t (const volatile int64_t *ptr); + return ep_rt_aot_volatile_load_int64_t(ptr); } static @@ -3064,7 +3048,9 @@ int64_t ep_rt_volatile_load_int64_t_without_barrier (const volatile int64_t *ptr) { STATIC_CONTRACT_NOTHROW; - return VolatileLoadWithoutBarrier ((int64_t *)ptr); + extern int64_t + ep_rt_aot_volatile_load_int64_t_without_barrier (const volatile int64_t *ptr); + return ep_rt_aot_volatile_load_int64_t_without_barrier(ptr); } static @@ -3075,7 +3061,11 @@ ep_rt_volatile_store_int64_t ( int64_t value) { STATIC_CONTRACT_NOTHROW; - VolatileStore ((int64_t *)ptr, value); + extern void + ep_rt_aot_volatile_store_int64_t ( + volatile int64_t *ptr, + int64_t value); + ep_rt_aot_volatile_store_int64_t(ptr, value); } static @@ -3086,7 +3076,11 @@ ep_rt_volatile_store_int64_t_without_barrier ( int64_t value) { STATIC_CONTRACT_NOTHROW; - VolatileStoreWithoutBarrier ((int64_t *)ptr, value); + extern void + ep_rt_aot_volatile_store_int64_t_without_barrier ( + volatile int64_t *ptr, + int64_t value); + ep_rt_aot_volatile_store_int64_t_without_barrier(ptr, value); } static @@ -3095,7 +3089,9 @@ void * ep_rt_volatile_load_ptr (volatile void **ptr) { STATIC_CONTRACT_NOTHROW; - return VolatileLoad ((void **)ptr); + extern void * + ep_rt_aot_volatile_load_ptr (volatile void **ptr); + return ep_rt_aot_volatile_load_ptr(ptr); } static @@ -3104,7 +3100,9 @@ void * ep_rt_volatile_load_ptr_without_barrier (volatile void **ptr) { STATIC_CONTRACT_NOTHROW; - return VolatileLoadWithoutBarrier ((void **)ptr); + extern void * + ep_rt_aot_volatile_load_ptr_without_barrier (volatile void **ptr); + return ep_rt_aot_volatile_load_ptr_without_barrier(ptr); } static @@ -3115,7 +3113,11 @@ ep_rt_volatile_store_ptr ( void *value) { STATIC_CONTRACT_NOTHROW; - VolatileStore ((void **)ptr, value); + extern void + ep_rt_aot_volatile_store_ptr ( + volatile void **ptr, + void *value); + ep_rt_aot_volatile_store_ptr(ptr, value); } static @@ -3126,7 +3128,11 @@ ep_rt_volatile_store_ptr_without_barrier ( void *value) { STATIC_CONTRACT_NOTHROW; - VolatileStoreWithoutBarrier ((void **)ptr, value); + extern void + ep_rt_aot_volatile_store_ptr_without_barrier ( + volatile void **ptr, + void *value); + ep_rt_aot_volatile_store_ptr_without_barrier(ptr, value); } #endif /* ENABLE_PERFTRACING */ diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h index ce5a0cb7fb9e5..991d1fd7d5ab6 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h @@ -8,7 +8,6 @@ #ifdef ENABLE_PERFTRACING -#include "gcenv.h" #include "EmptyContainers.h" #ifdef DEBUG diff --git a/src/coreclr/nativeaot/Runtime/eventpipeadapter.h b/src/coreclr/nativeaot/Runtime/eventpipeadapter.h index d580ca3fa5d38..4156cbf1e4680 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipeadapter.h +++ b/src/coreclr/nativeaot/Runtime/eventpipeadapter.h @@ -17,6 +17,13 @@ #include #include +#include "gcenv.h" +#include "regdisplay.h" +#include "StackFrameIterator.h" +#include "thread.h" +#include "holder.h" +#include "SpinLock.h" + class EventPipeAdapter final { public: diff --git a/src/coreclr/nativeaot/Runtime/eventpipeinternal.cpp b/src/coreclr/nativeaot/Runtime/eventpipeinternal.cpp index 41461fd7f47b3..3615daaeeb249 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipeinternal.cpp +++ b/src/coreclr/nativeaot/Runtime/eventpipeinternal.cpp @@ -4,6 +4,12 @@ #include "common.h" #include "eventpipeadapter.h" +#include "gcenv.h" +#include "regdisplay.h" +#include "StackFrameIterator.h" +#include "thread.h" +#include "SpinLock.h" + #ifdef FEATURE_PERFTRACING struct EventPipeEventInstanceData From e4109a22a40a3cd30e9c15de394dec524a269504 Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Thu, 2 Feb 2023 11:01:02 -0800 Subject: [PATCH 27/32] fix linux build break --- src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h index 2b9f7bd0ab65d..5a3e52a2e241e 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h @@ -13,6 +13,13 @@ #include "rhassert.h" +#ifdef TARGET_UNIX +#define __stdcall +#define sprintf_s snprintf +#define _stricmp strcasecmp +#define INFINITE 0xFFFFFFFF // Infinite timeout +#endif + #define STATIC_CONTRACT_NOTHROW #undef EP_INFINITE_WAIT @@ -25,7 +32,7 @@ #define EP_GCX_PREEMP_EXIT } #undef EP_ALWAYS_INLINE -#define EP_ALWAYS_INLINE FORCEINLINE +#define EP_ALWAYS_INLINE #undef EP_NEVER_INLINE #define EP_NEVER_INLINE From 4bb2a7aaaaaa394109b497216dde3b2cff680d29 Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Thu, 2 Feb 2023 12:19:40 -0800 Subject: [PATCH 28/32] missed a needed definition in Linux --- src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h | 1 - src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h index 5a3e52a2e241e..5c6f8ab834dc0 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h @@ -14,7 +14,6 @@ #include "rhassert.h" #ifdef TARGET_UNIX -#define __stdcall #define sprintf_s snprintf #define _stricmp strcasecmp #define INFINITE 0xFFFFFFFF // Infinite timeout diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h index 991d1fd7d5ab6..9aa547e6b4f4c 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-types-aot.h @@ -10,6 +10,10 @@ #include "EmptyContainers.h" +#ifdef TARGET_UNIX +#define __stdcall +#endif + #ifdef DEBUG #define EP_CHECKED_BUILD #endif From 3419c63d36e417f0448f2567ef1695b6b25b4562 Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Mon, 6 Feb 2023 15:04:18 -0800 Subject: [PATCH 29/32] inline eventpipe common source code --- src/coreclr/nativeaot/Runtime/CMakeLists.txt | 141 +----------------- src/coreclr/nativeaot/Runtime/CommonMacros.h | 4 +- .../nativeaot/Runtime/Full/CMakeLists.txt | 26 ---- .../Runtime/eventpipe/CMakeLists.txt | 115 ++++++++++++++ ...idation.cs => simpleprovidervalidation.cs} | 0 5 files changed, 118 insertions(+), 168 deletions(-) create mode 100644 src/coreclr/nativeaot/Runtime/eventpipe/CMakeLists.txt rename src/tests/tracing/eventpipe/simpleprovidervalidation/{Simpleprovidervalidation.cs => simpleprovidervalidation.cs} (100%) diff --git a/src/coreclr/nativeaot/Runtime/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/CMakeLists.txt index 970c5c54aee0a..e228b47d6ad0a 100644 --- a/src/coreclr/nativeaot/Runtime/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/CMakeLists.txt @@ -1,143 +1,3 @@ -set(EP_GENERATED_HEADER_PATH "${GENERATED_INCLUDE_DIR}") -include (${CLR_SRC_NATIVE_DIR}/eventpipe/configure.cmake) -include_directories(${EP_GENERATED_HEADER_PATH}) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) -set(AOT_EVENTPIPE_SHIM_DIR "${CMAKE_CURRENT_SOURCE_DIR}/eventpipe") - -set (SHARED_EVENTPIPE_SOURCE_DIR "${CLR_SRC_NATIVE_DIR}/eventpipe") -include_directories(${SHARED_EVENTPIPE_SOURCE_DIR}) - -set (AOT_EVENTPIPE_SHIM_SOURCES "") -set (AOT_EVENTPIPE_SHIM_HEADERS "") -set (AOT_EVENTPIPE_MANAGED_TO_NATIVE_SOURCES "") -set (SHARED_EVENTPIPE_SOURCES "") -set (SHARED_EVENTPIPE_HEADERS "") -set (SHARED_DIAGNOSTIC_SERVER_SOURCES "") -set (SHARED_DIAGNOSTIC_SERVER_HEADERS "") -set (AOT_EVENTPIPE_DISABLED_SOURCES "") - -list(APPEND SHARED_EVENTPIPE_SOURCES - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-sources.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-block.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-buffer.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-buffer-manager.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-config.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event-instance.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event-payload.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event-source.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-file.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-json-file.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-metadata-generator.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-provider.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-sample-profiler.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-session.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-session-provider.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-stack-contents.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-stream.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-thread.c -) - -list(APPEND SHARED_EVENTPIPE_HEADERS - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-block.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-buffer.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-buffer-manager.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-config.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-config-internals.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event-instance.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event-payload.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-event-source.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-file.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-getter-setter.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-ipc-pal-types.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-ipc-pal-types-forward.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-ipc-stream.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-json-file.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-metadata-generator.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-provider.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-provider-internals.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-rt.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-rt-config.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-rt-types.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-sample-profiler.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-session.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-session-provider.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-stack-contents.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-stream.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-thread.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-types.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ep-types-forward.h -) - -list(APPEND SHARED_DIAGNOSTIC_SERVER_SOURCES - ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-sources.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-dump-protocol.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-eventpipe-protocol.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-ipc-pal-namedpipe.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-ipc.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-process-protocol.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-profiler-protocol.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-protocol.c - ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-server.c -) - -list(APPEND SHARED_DIAGNOSTIC_SERVER_HEADERS - ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-dump-protocol.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-eventpipe-protocol.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-getter-setter.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-ipc.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-ipc-pal.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-ipc-pal-types.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-ipc-pal-namedpipe.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-process-protocol.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-profiler-protocol.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-protocol.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-rt.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-rt-config.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-rt-types.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-server.h - ${SHARED_EVENTPIPE_SOURCE_DIR}/ds-types.h -) - -list(APPEND AOT_EVENTPIPE_SHIM_SOURCES - ${AOT_EVENTPIPE_SHIM_DIR}/ep-rt-aot.cpp -) - -list(APPEND AOT_EVENTPIPE_SHIM_HEADERS - ${AOT_EVENTPIPE_SHIM_DIR}/ds-rt-aot.h - ${AOT_EVENTPIPE_SHIM_DIR}/ds-rt-types-aot.h - ${AOT_EVENTPIPE_SHIM_DIR}/ep-rt-aot.h - ${AOT_EVENTPIPE_SHIM_DIR}/ep-rt-config-aot.h - ${AOT_EVENTPIPE_SHIM_DIR}/ep-rt-types-aot.h -) - -list(APPEND AOT_EVENTPIPE_MANAGED_TO_NATIVE_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/eventpipeinternal.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/eventpipeadapter.h - ${CMAKE_CURRENT_SOURCE_DIR}/diagnosticserveradapter.h - ${CMAKE_CURRENT_SOURCE_DIR}/EnabledEventPipeInterface.cpp -) - -list(APPEND EVENTPIPE_SOURCES - ${AOT_EVENTPIPE_SHIM_SOURCES} - ${AOT_EVENTPIPE_SHIM_HEADERS} - ${AOT_EVENTPIPE_MANAGED_TO_NATIVE_SOURCES} - ${SHARED_EVENTPIPE_SOURCES} - ${SHARED_EVENTPIPE_HEADERS} - ${SHARED_DIAGNOSTIC_SERVER_SOURCES} - ${SHARED_DIAGNOSTIC_SERVER_HEADERS} - ${SHARED_EVENTPIPE_CONFIG_HEADERS} -) - -list(APPEND AOT_EVENTPIPE_DISABLED_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/DisabledEventPipeInterface.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/disabledeventpipeinternal.cpp -) - set(GC_DIR ../../gc) set(COMMON_RUNTIME_SOURCES @@ -401,6 +261,7 @@ convert_to_absolute_path(RUNTIME_SOURCES_ARCH_ASM ${RUNTIME_SOURCES_ARCH_ASM}) if(NOT CLR_CMAKE_TARGET_ARCH_WASM) add_subdirectory(Full) + add_subdirectory(eventpipe) else() add_subdirectory(Portable) endif() diff --git a/src/coreclr/nativeaot/Runtime/CommonMacros.h b/src/coreclr/nativeaot/Runtime/CommonMacros.h index 98dff271dff45..b7a106bda7ac0 100644 --- a/src/coreclr/nativeaot/Runtime/CommonMacros.h +++ b/src/coreclr/nativeaot/Runtime/CommonMacros.h @@ -66,7 +66,7 @@ // has not been included (even though though windows.h does not define these services); in // all other cases the services need to be defined here. -#if !(defined(__GCENV_BASE_INCLUDED__) && !defined(_INC_WINDOWS)) +#if !defined(__GCENV_BASE_INCLUDED__) // // This macro returns val rounded up as necessary to be a multiple of alignment; alignment must be a power of 2 @@ -79,7 +79,7 @@ inline uintptr_t ALIGN_DOWN(uintptr_t val, uintptr_t alignment); template inline T* ALIGN_DOWN(T* val, uintptr_t alignment); -#endif // !(defined(__GCENV_BASE_INCLUDED__) && !defined(_INC_WINDOWS)) +#endif // !defined(__GCENV_BASE_INCLUDED__) inline bool IS_ALIGNED(uintptr_t val, uintptr_t alignment); template diff --git a/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt index c2088b3ddcc04..22af5f44eba20 100644 --- a/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt @@ -7,7 +7,6 @@ project(Runtime) set(CMAKE_INCLUDE_CURRENT_DIR ON) add_definitions(-DFEATURE_RX_THUNKS) -add_definitions(-DFEATURE_PERFTRACING) if (CLR_CMAKE_TARGET_WIN32) if (CLR_CMAKE_HOST_ARCH_ARM OR CLR_CMAKE_HOST_ARCH_ARM64) @@ -25,19 +24,12 @@ add_library(Runtime.WorkstationGC STATIC ${COMMON_RUNTIME_SOURCES} ${FULL_RUNTIM add_library(Runtime.ServerGC STATIC ${COMMON_RUNTIME_SOURCES} ${FULL_RUNTIME_SOURCES} ${RUNTIME_SOURCES_ARCH_ASM} ${SERVER_GC_SOURCES} ${RUNTIME_ARCH_ASM_OBJECTS}) -add_library(eventpipe-enabled STATIC ${EVENTPIPE_SOURCES}) -add_library(eventpipe-disabled STATIC ${AOT_EVENTPIPE_DISABLED_SOURCES}) - target_compile_definitions(Runtime.ServerGC PRIVATE -DFEATURE_SVR_GC) if (CLR_CMAKE_TARGET_WIN32) add_library(Runtime.ServerGC.GuardCF STATIC ${COMMON_RUNTIME_SOURCES} ${FULL_RUNTIME_SOURCES} ${RUNTIME_SOURCES_ARCH_ASM} ${SERVER_GC_SOURCES} ${RUNTIME_ARCH_ASM_OBJECTS}) target_compile_definitions(Runtime.ServerGC.GuardCF PRIVATE -DFEATURE_SVR_GC) target_compile_options(Runtime.ServerGC.GuardCF PRIVATE $<$,$>:/guard:cf>) - - add_library(eventpipe-disabled.GuardCF STATIC ${AOT_EVENTPIPE_DISABLED_SOURCES}) - install_static_library(eventpipe-disabled.GuardCF aotsdk nativeaot) - target_compile_options(eventpipe-disabled.GuardCF PRIVATE $<$,$>:/guard:cf>) endif (CLR_CMAKE_TARGET_WIN32) # Get the current list of definitions @@ -71,21 +63,6 @@ add_custom_command( set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/AsmOffsets.inc" PROPERTIES GENERATED TRUE) -set_source_files_properties(${SHARED_EVENTPIPE_SOURCES} PROPERTIES LANGUAGE CXX) -set_source_files_properties(${SHARED_DIAGNOSTIC_SERVER_SOURCES} PROPERTIES LANGUAGE CXX) - -if(CLR_CMAKE_HOST_UNIX) - if (CMAKE_VERSION VERSION_GREATER 3.11 OR CMAKE_VERSION VERSION_EQUAL 3.11) - set_source_files_properties(${SHARED_EVENTPIPE_SOURCES} PROPERTIES COMPILE_OPTIONS -xc++) - set_source_files_properties(${SHARED_DIAGNOSTIC_SERVER_SOURCES} PROPERTIES COMPILE_OPTIONS -xc++) - endif() -endif(CLR_CMAKE_HOST_UNIX) - -if (WIN32) - set_source_files_properties(${SHARED_EVENTPIPE_SOURCES} PROPERTIES COMPILE_FLAGS "/FI\"${RUNTIME_DIR}/eventpipe/NativeaotEventPipeSupport.h\"") - set_source_files_properties(${SHARED_DIAGNOSTIC_SERVER_SOURCES} PROPERTIES COMPILE_FLAGS "/FI\"${RUNTIME_DIR}/eventpipe/NativeaotEventPipeSupport.h\"") -endif() - # Runtime.WorkstationGC and Runtime.ServerGC share AsmOffsets.inc and assembler helpers (for Windows ARM/ARM64). # Avoid a race condition by adding this target as a dependency for both libraries. add_custom_target( @@ -101,9 +78,6 @@ endif (CLR_CMAKE_TARGET_WIN32) install_static_library(Runtime.WorkstationGC aotsdk nativeaot) install_static_library(Runtime.ServerGC aotsdk nativeaot) -install_static_library(eventpipe-enabled aotsdk nativeaot) -install_static_library(eventpipe-disabled aotsdk nativeaot) if (CLR_CMAKE_TARGET_WIN32) install_static_library(Runtime.ServerGC.GuardCF aotsdk nativeaot) - install_static_library(eventpipe-disabled.GuardCF aotsdk nativeaot) endif (CLR_CMAKE_TARGET_WIN32) diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/eventpipe/CMakeLists.txt new file mode 100644 index 0000000000000..7b967f42ea82e --- /dev/null +++ b/src/coreclr/nativeaot/Runtime/eventpipe/CMakeLists.txt @@ -0,0 +1,115 @@ +project(Runtime) + +set(EP_GENERATED_HEADER_PATH "${GENERATED_INCLUDE_DIR}") +include (${CLR_SRC_NATIVE_DIR}/eventpipe/configure.cmake) +include_directories(${EP_GENERATED_HEADER_PATH}) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(AOT_EVENTPIPE_SHIM_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + +add_definitions(-DFEATURE_RX_THUNKS) + +# we need this definition to inline cmake file in eventpipe +if(NOT DEFINED FEATURE_PERFTRACING) + set(FEATURE_PERFTRACING 1) + set(NEEDED_PERF_AOT_FLAG 1) +endif() + +set (EVENTPIPE_SOURCES "") +set (EVENTPIPE_HEADERS "") +set (CORECLR_EVENTPIPE_SHIM_SOURCES "") +set (CORECLR_EVENTPIPE_SHIM_HEADERS "") + +set (SHARED_EVENTPIPE_SOURCE_PATH "${CLR_SRC_NATIVE_DIR}/eventpipe") +include (${SHARED_EVENTPIPE_SOURCE_PATH}/CMakeLists.txt) + +# unset the FEATURE_PERFTRACING if we set it above +if(DEFINED NEEDED_PERF_AOT_FLAG) + set(FEATURE_PERFTRACING 0) + set(NEEDED_PERF_AOT_FLAG 0) +endif() + +list(APPEND SHARED_DIAGNOSTIC_SERVER_SOURCES + ds-ipc-pal-namedpipe.c +) + +list(APPEND SHARED_DIAGNOSTIC_SERVER_HEADERS + ds-ipc-pal-namedpipe.h +) + +list(APPEND EVENTPIPE_SOURCES + ${SHARED_EVENTPIPE_SOURCES} + ${SHARED_DIAGNOSTIC_SERVER_SOURCES} +) + +list(APPEND EVENTPIPE_HEADERS + ${SHARED_EVENTPIPE_HEADERS} + ${SHARED_DIAGNOSTIC_SERVER_HEADERS} +) + +addprefix(EVENTPIPE_SOURCES ${SHARED_EVENTPIPE_SOURCE_PATH} "${EVENTPIPE_SOURCES}") +addprefix(EVENTPIPE_HEADERS ${SHARED_EVENTPIPE_SOURCE_PATH} "${EVENTPIPE_HEADERS}") + +set_source_files_properties(${SHARED_EVENTPIPE_SOURCE_PATH}/ep-sources.c PROPERTIES COMPILE_DEFINITIONS EP_FORCE_INCLUDE_SOURCE_FILES) +set_source_files_properties(${SHARED_EVENTPIPE_SOURCE_PATH}/ds-sources.c PROPERTIES COMPILE_DEFINITIONS DS_FORCE_INCLUDE_SOURCE_FILES) + +set_source_files_properties(${EVENTPIPE_SOURCES} PROPERTIES LANGUAGE CXX) + +if(CLR_CMAKE_HOST_UNIX) + if (CMAKE_VERSION VERSION_GREATER 3.11 OR CMAKE_VERSION VERSION_EQUAL 3.11) + set_source_files_properties(${EVENTPIPE_SOURCES} PROPERTIES COMPILE_OPTIONS -xc++) + else(CMAKE_VERSION VERSION_GREATER 3.11 OR CMAKE_VERSION VERSION_EQUAL 3.11) + add_compile_options(-xc++) + endif() +endif(CLR_CMAKE_HOST_UNIX) + +if (WIN32) + set_source_files_properties(${EVENTPIPE_SOURCES} PROPERTIES COMPILE_FLAGS "/FI\"${RUNTIME_DIR}/eventpipe/NativeaotEventPipeSupport.h\"") +endif() + +list(APPEND AOT_EVENTPIPE_SHIM_SOURCES + ${AOT_EVENTPIPE_SHIM_DIR}/ep-rt-aot.cpp +) + +list(APPEND AOT_EVENTPIPE_SHIM_HEADERS + ${AOT_EVENTPIPE_SHIM_DIR}/ds-rt-aot.h + ${AOT_EVENTPIPE_SHIM_DIR}/ds-rt-types-aot.h + ${AOT_EVENTPIPE_SHIM_DIR}/ep-rt-aot.h + ${AOT_EVENTPIPE_SHIM_DIR}/ep-rt-config-aot.h + ${AOT_EVENTPIPE_SHIM_DIR}/ep-rt-types-aot.h +) + +list(APPEND AOT_EVENTPIPE_MANAGED_TO_NATIVE_SOURCES + ${RUNTIME_DIR}/eventpipeinternal.cpp + ${RUNTIME_DIR}/eventpipeadapter.h + ${RUNTIME_DIR}/diagnosticserveradapter.h + ${RUNTIME_DIR}/EnabledEventPipeInterface.cpp +) + +list(APPEND EVENTPIPE_SOURCES + ${AOT_EVENTPIPE_SHIM_SOURCES} + ${AOT_EVENTPIPE_SHIM_HEADERS} + ${AOT_EVENTPIPE_MANAGED_TO_NATIVE_SOURCES} + ${SHARED_EVENTPIPE_CONFIG_HEADERS} +) + +list(APPEND AOT_EVENTPIPE_DISABLED_SOURCES + ${RUNTIME_DIR}/DisabledEventPipeInterface.cpp + ${RUNTIME_DIR}/disabledeventpipeinternal.cpp +) + +add_definitions(-DFEATURE_PERFTRACING) + +add_library(eventpipe-enabled STATIC ${EVENTPIPE_SOURCES}) +add_library(eventpipe-disabled STATIC ${AOT_EVENTPIPE_DISABLED_SOURCES}) + +if (CLR_CMAKE_TARGET_WIN32) + add_library(eventpipe-disabled.GuardCF STATIC ${AOT_EVENTPIPE_DISABLED_SOURCES}) + target_compile_options(eventpipe-disabled.GuardCF PRIVATE $<$,$>:/guard:cf>) +endif (CLR_CMAKE_TARGET_WIN32) + +install_static_library(eventpipe-enabled aotsdk nativeaot) +install_static_library(eventpipe-disabled aotsdk nativeaot) +if (CLR_CMAKE_TARGET_WIN32) + install_static_library(eventpipe-disabled.GuardCF aotsdk nativeaot) +endif (CLR_CMAKE_TARGET_WIN32) diff --git a/src/tests/tracing/eventpipe/simpleprovidervalidation/Simpleprovidervalidation.cs b/src/tests/tracing/eventpipe/simpleprovidervalidation/simpleprovidervalidation.cs similarity index 100% rename from src/tests/tracing/eventpipe/simpleprovidervalidation/Simpleprovidervalidation.cs rename to src/tests/tracing/eventpipe/simpleprovidervalidation/simpleprovidervalidation.cs From 97dfa128d58120e81bf13c2bd7d75698fe208e01 Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Tue, 7 Feb 2023 10:53:56 -0800 Subject: [PATCH 30/32] Adding Evenpipe lib to a lib test --- .../tests/Microsoft.Extensions.Logging.EventSource.Tests.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/Microsoft.Extensions.Logging.EventSource/tests/Microsoft.Extensions.Logging.EventSource.Tests.csproj b/src/libraries/Microsoft.Extensions.Logging.EventSource/tests/Microsoft.Extensions.Logging.EventSource.Tests.csproj index cc24d8f4a83ea..22abed2826235 100644 --- a/src/libraries/Microsoft.Extensions.Logging.EventSource/tests/Microsoft.Extensions.Logging.EventSource.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.EventSource/tests/Microsoft.Extensions.Logging.EventSource.Tests.csproj @@ -4,6 +4,7 @@ $(NetCoreAppCurrent);$(NetFrameworkMinimum) true true + true From c10ec13e81ed578a93bc9d563ec20e424e0efe83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Wed, 8 Feb 2023 15:28:33 +0900 Subject: [PATCH 31/32] Small cleanups * Undo unnecessary changes * Make sure runtime can build without FEATURE_PERFTRACING --- src/coreclr/nativeaot/Runtime/CMakeLists.txt | 15 ++++++++++++--- src/coreclr/nativeaot/Runtime/CommonMacros.h | 8 ++------ .../nativeaot/Runtime/CommonMacros.inl | 8 ++------ src/coreclr/nativeaot/Runtime/PalRedhawk.h | 19 +++---------------- .../Runtime/eventpipe/CMakeLists.txt | 16 ---------------- src/coreclr/nativeaot/Runtime/loglf.h | 2 -- src/coreclr/nativeaot/Runtime/startup.cpp | 9 +++++++++ src/coreclr/nativeaot/Runtime/thread.h | 4 ++-- 8 files changed, 30 insertions(+), 51 deletions(-) diff --git a/src/coreclr/nativeaot/Runtime/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/CMakeLists.txt index e228b47d6ad0a..8c80cbe2f37a0 100644 --- a/src/coreclr/nativeaot/Runtime/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/CMakeLists.txt @@ -36,8 +36,6 @@ set(COMMON_RUNTIME_SOURCES UniversalTransitionHelpers.cpp yieldprocessornormalized.cpp - EventPipeInterface.h - ${GC_DIR}/gceventstatus.cpp ${GC_DIR}/gcload.cpp ${GC_DIR}/gcconfig.cpp @@ -209,6 +207,14 @@ list(APPEND RUNTIME_SOURCES_ARCH_ASM convert_to_absolute_path(ARCH_SOURCES_DIR ${ARCH_SOURCES_DIR}) include_directories(${ARCH_SOURCES_DIR}) +if(NOT CLR_CMAKE_TARGET_ARCH_WASM) + set(FEATURE_PERFTRACING 1) +endif() + +if(FEATURE_PERFTRACING) + add_definitions(-DFEATURE_PERFTRACING) +endif() + add_definitions(-DFEATURE_BASICFREEZE) add_definitions(-DFEATURE_CONSERVATIVE_GC) add_definitions(-DFEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP) @@ -261,11 +267,14 @@ convert_to_absolute_path(RUNTIME_SOURCES_ARCH_ASM ${RUNTIME_SOURCES_ARCH_ASM}) if(NOT CLR_CMAKE_TARGET_ARCH_WASM) add_subdirectory(Full) - add_subdirectory(eventpipe) else() add_subdirectory(Portable) endif() +if(FEATURE_PERFTRACING) + add_subdirectory(eventpipe) +endif() + if (CLR_CMAKE_TARGET_UNIX) add_library(numasupportdynamic STATIC ${GC_DIR}/unix/numasupport.dynamic.cpp) install_static_library(numasupportdynamic aotsdk nativeaot) diff --git a/src/coreclr/nativeaot/Runtime/CommonMacros.h b/src/coreclr/nativeaot/Runtime/CommonMacros.h index b7a106bda7ac0..a4a82be3753e5 100644 --- a/src/coreclr/nativeaot/Runtime/CommonMacros.h +++ b/src/coreclr/nativeaot/Runtime/CommonMacros.h @@ -62,11 +62,7 @@ #endif #endif -// TODO: gcenv.base.h provides these definitions only if it has been included and windows.h -// has not been included (even though though windows.h does not define these services); in -// all other cases the services need to be defined here. - -#if !defined(__GCENV_BASE_INCLUDED__) +#ifndef __GCENV_BASE_INCLUDED__ // // This macro returns val rounded up as necessary to be a multiple of alignment; alignment must be a power of 2 @@ -79,7 +75,7 @@ inline uintptr_t ALIGN_DOWN(uintptr_t val, uintptr_t alignment); template inline T* ALIGN_DOWN(T* val, uintptr_t alignment); -#endif // !defined(__GCENV_BASE_INCLUDED__) +#endif // !__GCENV_BASE_INCLUDED__ inline bool IS_ALIGNED(uintptr_t val, uintptr_t alignment); template diff --git a/src/coreclr/nativeaot/Runtime/CommonMacros.inl b/src/coreclr/nativeaot/Runtime/CommonMacros.inl index b37eab9d55079..a9ad0b2b6764e 100644 --- a/src/coreclr/nativeaot/Runtime/CommonMacros.inl +++ b/src/coreclr/nativeaot/Runtime/CommonMacros.inl @@ -1,11 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// TODO: gcenv.base.h provides these definitions only if it has been included and windows.h -// has not been included (even though though windows.h does not define these services); in -// all other cases the services need to be defined here. - -#if !(defined(__GCENV_BASE_INCLUDED__) && !defined(_INC_WINDOWS)) +#ifndef __GCENV_BASE_INCLUDED__ // // This macro returns val rounded up as necessary to be a multiple of alignment; alignment must be a power of 2 @@ -40,7 +36,7 @@ inline T* ALIGN_DOWN(T* val, uintptr_t alignment) return reinterpret_cast(ALIGN_DOWN(reinterpret_cast(val), alignment)); } -#endif // !(defined(__GCENV_BASE_INCLUDED__) && !defined(_INC_WINDOWS)) +#endif // !__GCENV_BASE_INCLUDED__ inline bool IS_ALIGNED(uintptr_t val, uintptr_t alignment) { diff --git a/src/coreclr/nativeaot/Runtime/PalRedhawk.h b/src/coreclr/nativeaot/Runtime/PalRedhawk.h index 0188a26868ed8..1ffbe94c41811 100644 --- a/src/coreclr/nativeaot/Runtime/PalRedhawk.h +++ b/src/coreclr/nativeaot/Runtime/PalRedhawk.h @@ -49,9 +49,6 @@ #endif // !_MSC_VER -// defined in gcrhenv.cpp -bool __SwitchToThread(uint32_t dwSleepMSec, uint32_t dwSwitchCount); - #ifndef _INC_WINDOWS //#ifndef DACCESS_COMPILE @@ -104,6 +101,9 @@ typedef struct _GUID { #define DECLARE_HANDLE(_name) typedef HANDLE _name +// defined in gcrhenv.cpp +bool __SwitchToThread(uint32_t dwSleepMSec, uint32_t dwSwitchCount); + struct FILETIME { uint32_t dwLowDateTime; @@ -602,19 +602,6 @@ extern uint32_t g_RhNumberOfProcessors; #endif // !_INC_WINDOWS #endif // !DACCESS_COMPILE -// TODO: Duplicate the definition from PalRedhawkFunctions.h to allow the EventPipe code to -// access PalEventWrite even though the PalRedhawkFunctions.h services are generally not -// available in NativeAOT runtime contexts where windows.h has been included. -#ifdef _INC_WINDOWS -#ifdef BUILDING_SHARED_NATIVEAOT_EVENTPIPE_CODE -extern "C" uint32_t __stdcall EventWrite(REGHANDLE, const EVENT_DESCRIPTOR *, uint32_t, EVENT_DATA_DESCRIPTOR *); -inline uint32_t PalEventWrite(REGHANDLE arg1, const EVENT_DESCRIPTOR * arg2, uint32_t arg3, EVENT_DATA_DESCRIPTOR * arg4) -{ - return EventWrite(arg1, arg2, arg3, arg4); -} -#endif // BUILDING_SHARED_NATIVEAOT_EVENTPIPE_CODE -#endif // _INC_WINDOWS - // The Redhawk PAL must be initialized before any of its exports can be called. Returns true for a successful // initialization and false on failure. REDHAWK_PALIMPORT bool REDHAWK_PALAPI PalInit(); diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/eventpipe/CMakeLists.txt index 7b967f42ea82e..39d658db4b18d 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/eventpipe/CMakeLists.txt @@ -7,14 +7,6 @@ include_directories(${EP_GENERATED_HEADER_PATH}) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(AOT_EVENTPIPE_SHIM_DIR "${CMAKE_CURRENT_SOURCE_DIR}") -add_definitions(-DFEATURE_RX_THUNKS) - -# we need this definition to inline cmake file in eventpipe -if(NOT DEFINED FEATURE_PERFTRACING) - set(FEATURE_PERFTRACING 1) - set(NEEDED_PERF_AOT_FLAG 1) -endif() - set (EVENTPIPE_SOURCES "") set (EVENTPIPE_HEADERS "") set (CORECLR_EVENTPIPE_SHIM_SOURCES "") @@ -23,12 +15,6 @@ set (CORECLR_EVENTPIPE_SHIM_HEADERS "") set (SHARED_EVENTPIPE_SOURCE_PATH "${CLR_SRC_NATIVE_DIR}/eventpipe") include (${SHARED_EVENTPIPE_SOURCE_PATH}/CMakeLists.txt) -# unset the FEATURE_PERFTRACING if we set it above -if(DEFINED NEEDED_PERF_AOT_FLAG) - set(FEATURE_PERFTRACING 0) - set(NEEDED_PERF_AOT_FLAG 0) -endif() - list(APPEND SHARED_DIAGNOSTIC_SERVER_SOURCES ds-ipc-pal-namedpipe.c ) @@ -98,8 +84,6 @@ list(APPEND AOT_EVENTPIPE_DISABLED_SOURCES ${RUNTIME_DIR}/disabledeventpipeinternal.cpp ) -add_definitions(-DFEATURE_PERFTRACING) - add_library(eventpipe-enabled STATIC ${EVENTPIPE_SOURCES}) add_library(eventpipe-disabled STATIC ${AOT_EVENTPIPE_DISABLED_SOURCES}) diff --git a/src/coreclr/nativeaot/Runtime/loglf.h b/src/coreclr/nativeaot/Runtime/loglf.h index a3752fb167e67..ff6abd88b9ff7 100644 --- a/src/coreclr/nativeaot/Runtime/loglf.h +++ b/src/coreclr/nativeaot/Runtime/loglf.h @@ -10,10 +10,8 @@ DEFINE_LOG_FACILITY(LF_GCALLOC ,0x00000004) DEFINE_LOG_FACILITY(LF_GCROOTS ,0x00000008) DEFINE_LOG_FACILITY(LF_STARTUP ,0x00000010) // Log startup and shutdown failures DEFINE_LOG_FACILITY(LF_STACKWALK ,0x00000020) -DEFINE_LOG_FACILITY(LF_DIAGNOSTICS_PORT, 0x00000040) // LF_ALWAYS 0x80000000 // make certain you don't try to use this bit for a real facility // LF_ALL 0xFFFFFFFF // #undef DEFINE_LOG_FACILITY -#define INFINITE 0xFFFFFFFF // Infinite timeout diff --git a/src/coreclr/nativeaot/Runtime/startup.cpp b/src/coreclr/nativeaot/Runtime/startup.cpp index bcf60ee6d6aa5..d1e240378e802 100644 --- a/src/coreclr/nativeaot/Runtime/startup.cpp +++ b/src/coreclr/nativeaot/Runtime/startup.cpp @@ -25,7 +25,10 @@ #include "stressLog.h" #include "RestrictedCallouts.h" #include "yieldprocessornormalized.h" + +#ifdef FEATURE_PERFTRACING #include "EventPipeInterface.h" +#endif #ifndef DACCESS_COMPILE @@ -98,11 +101,13 @@ static bool InitDLL(HANDLE hPalInstance) return false; #endif +#ifdef FEATURE_PERFTRACING // Initialize EventPipe EventPipeAdapter_Initialize(); // Initialize DS DiagnosticServerAdapter_Initialize(); DiagnosticServerAdapter_PauseForDiagnosticsMonitor(); +#endif // // Initialize support for registering GC and HandleTable callouts. @@ -148,10 +153,12 @@ static bool InitDLL(HANDLE hPalInstance) STARTUP_TIMELINE_EVENT(GC_INIT_COMPLETE); +#ifdef FEATURE_PERFTRACING // Finish setting up rest of EventPipe - specifically enable SampleProfiler if it was requested at startup. // SampleProfiler needs to cooperate with the GC which hasn't fully finished setting up in the first part of the // EventPipe initialization, so this is done after the GC has been fully initialized. EventPipeAdapter_FinishInitialize(); +#endif #ifndef USE_PORTABLE_HELPERS if (!DetectCPUFeatures()) @@ -472,8 +479,10 @@ static void __cdecl OnProcessExit() Thread* currentThread = ThreadStore::RawGetCurrentThread(); g_threadPerformingShutdown = currentThread; +#ifdef FEATURE_PERFTRACING EventPipeAdapter_Shutdown(); DiagnosticServerAdapter_Shutdown(); +#endif } #endif diff --git a/src/coreclr/nativeaot/Runtime/thread.h b/src/coreclr/nativeaot/Runtime/thread.h index 4e657c8f171a9..698d88abab485 100644 --- a/src/coreclr/nativeaot/Runtime/thread.h +++ b/src/coreclr/nativeaot/Runtime/thread.h @@ -331,10 +331,10 @@ typedef DacScanCallbackData EnumGcRefScanContext; typedef void EnumGcRefCallbackFunc(PTR_PTR_Object, EnumGcRefScanContext* callbackData, uint32_t flags); #else // DACCESS_COMPILE -#if !(defined(__GCENV_BASE_INCLUDED__) && !defined(FEATURE_PERFTRACING)) +#ifndef __GCENV_BASE_INCLUDED__ struct ScanContext; typedef void promote_func(PTR_PTR_Object, ScanContext*, unsigned); -#endif // !__GCENV_BASE_INCLUDED__ && FEATURE_PERFTRACING +#endif // !__GCENV_BASE_INCLUDED__ typedef promote_func EnumGcRefCallbackFunc; typedef ScanContext EnumGcRefScanContext; From 1cd0dc596042659e34e578fd79ac13d3178fb73d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Wed, 8 Feb 2023 16:51:17 +0900 Subject: [PATCH 32/32] Fix linux build --- src/coreclr/nativeaot/Runtime/thread.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/coreclr/nativeaot/Runtime/thread.h b/src/coreclr/nativeaot/Runtime/thread.h index 698d88abab485..d42a78e922f20 100644 --- a/src/coreclr/nativeaot/Runtime/thread.h +++ b/src/coreclr/nativeaot/Runtime/thread.h @@ -331,10 +331,8 @@ typedef DacScanCallbackData EnumGcRefScanContext; typedef void EnumGcRefCallbackFunc(PTR_PTR_Object, EnumGcRefScanContext* callbackData, uint32_t flags); #else // DACCESS_COMPILE -#ifndef __GCENV_BASE_INCLUDED__ struct ScanContext; typedef void promote_func(PTR_PTR_Object, ScanContext*, unsigned); -#endif // !__GCENV_BASE_INCLUDED__ typedef promote_func EnumGcRefCallbackFunc; typedef ScanContext EnumGcRefScanContext;