Inline GetLastError and SetLastError. (mono/mono#15560)
authorJay Krell <jaykrell@microsoft.com>
Mon, 8 Jul 2019 07:42:54 +0000 (00:42 -0700)
committerJohan Lorensson <lateralusx.github@gmail.com>
Mon, 8 Jul 2019 07:42:54 +0000 (09:42 +0200)
Commit migrated from https://github.com/mono/mono/commit/963ba77863303f6a74e8b5bfe6e5c05bbbb19ccb

src/mono/mono/utils/mono-error-internals.h
src/mono/mono/utils/mono-threads.h

index 03a57df..76a6666 100644 (file)
@@ -284,4 +284,60 @@ mono_error_set_specific (MonoError *error, int error_code, const char *missing_m
 void
 mono_error_set_first_argument (MonoError *oerror, const char *first_argument);
 
+#if HOST_WIN32
+#if HOST_X86 || HOST_AMD64
+
+#include <windows.h>
+
+// Single instruction inlinable form of GetLastError.
+//
+// Naming violation so can search disassembly for GetLastError.
+//
+#define GetLastError mono_GetLastError
+
+static inline
+unsigned long
+__stdcall
+GetLastError (void)
+{
+#if HOST_X86
+    return __readfsdword (0x34);
+#elif HOST_AMD64
+    return __readgsdword (0x68);
+#else
+#error Unreachable, see above.
+#endif
+}
+
+// Single instruction inlinable valid subset of SetLastError.
+//
+// Naming violation so can search disassembly for SetLastError.
+//
+// This is useful, for example, if you want to set a breakpoint
+// on SetLastError, but do not want to break on merely "restoring" it,
+// only "originating" it.
+//
+// A generic name is used in case there are other use-cases.
+//
+static inline
+void
+__stdcall
+mono_SetLastError (unsigned long err)
+{
+#if HOST_X86
+    __writefsdword (0x34, err);
+#elif HOST_AMD64
+    __writegsdword (0x68, err);
+#else
+#error Unreachable, see above.
+#endif
+}
+
+#else // arm, arm64, etc.
+
+#define mono_SetLastError SetLastError
+
+#endif // processor
+#endif // win32
+
 #endif
index dfd183a..1a0ce78 100644 (file)
@@ -21,6 +21,7 @@
 #include <mono/utils/mono-coop-semaphore.h>
 #include <mono/utils/os-event.h>
 #include <mono/utils/refcount.h>
+#include <mono/utils/mono-error-internals.h>
 
 #include <glib.h>
 #include <config.h>
@@ -829,12 +830,12 @@ void
 mono_win32_abort_blocking_io_call (THREAD_INFO_TYPE *info);
 
 #define W32_DEFINE_LAST_ERROR_RESTORE_POINT \
-       DWORD _last_error_restore_point = GetLastError ();
+       const DWORD _last_error_restore_point = GetLastError ();
 
 #define W32_RESTORE_LAST_ERROR_FROM_RESTORE_POINT \
                /* Only restore if changed to prevent unecessary writes. */ \
                if (GetLastError () != _last_error_restore_point) \
-                       SetLastError (_last_error_restore_point);
+                       mono_SetLastError (_last_error_restore_point);
 
 #else