void
sgen_qsort (void *base, size_t nel, size_t width, int (*compar) (const void*, const void*))
{
+#ifndef _MSC_VER
unsigned char pivot_tmp [width];
unsigned char swap_tmp [width];
+#else
+ unsigned char* pivot_tmp = (unsigned char*) alloca(width);
+ unsigned char* swap_tmp = (unsigned char*) alloca(width);
+#endif
qsort_rec (base, nel, width, compar, pivot_tmp, swap_tmp);
}
# define fprintf(__ignore, ...) g_log ("mono-gc", G_LOG_LEVEL_MESSAGE, __VA_ARGS__)
#endif
-#define RETURN_ADDRESS(N) (__builtin_extract_return_addr (__builtin_return_address (N)))
+#ifdef __GNUC__
+
+#define RETURN_ADDRESS_N(N) (__builtin_extract_return_addr (__builtin_return_address (N)))
+#define RETURN_ADDRESS() RETURN_ADDRESS_N(0)
+
+#elif defined(_MSC_VER)
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void *_ReturnAddress(void);
+#pragma intrinsic(_ReturnAddress)
+#define RETURN_ADDRESS() _ReturnAddress()
+#define RETURN_ADDRESS_N(N) NULL
+
+#else
+
+#define RETURN_ADDRESS() NULL
+#define RETURN_ADDRESS_N(N) NULL
+
+#endif
static MonoTraceSpec trace_spec;
g_free (fname);
if (!ebp) {
- printf (") ip: %p\n", RETURN_ADDRESS (1));
+ printf (") ip: %p\n", RETURN_ADDRESS_N (1));
return;
}
if (method->is_inflated) {
/* FIXME: Might be better to pass the ji itself */
- MonoJitInfo *ji = mini_jit_info_table_find (mono_domain_get (), RETURN_ADDRESS (0), NULL);
+ MonoJitInfo *ji = mini_jit_info_table_find (mono_domain_get (), RETURN_ADDRESS (), NULL);
if (ji) {
gsctx = mono_jit_info_get_generic_sharing_context (ji);
if (gsctx && (gsctx->var_is_vt || gsctx->mvar_is_vt)) {
if (method->is_inflated) {
/* FIXME: Might be better to pass the ji itself */
- MonoJitInfo *ji = mini_jit_info_table_find (mono_domain_get (), RETURN_ADDRESS (0), NULL);
+ MonoJitInfo *ji = mini_jit_info_table_find (mono_domain_get (), RETURN_ADDRESS (), NULL);
if (ji) {
gsctx = mono_jit_info_get_generic_sharing_context (ji);
if (gsctx && (gsctx->var_is_vt || gsctx->mvar_is_vt)) {
printf ("(unknown return type %x)", mono_method_signature (method)->ret->type);
}
- //printf (" ip: %p\n", RETURN_ADDRESS (1));
+ //printf (" ip: %p\n", RETURN_ADDRESS_N (1));
printf ("\n");
fflush (stdout);
}
}
#endif
+#if defined(_MSC_VER) && !defined(InterlockedAdd)
+/* MSVC before 2013 only defines InterlockedAdd* for the Itanium architecture */
+static inline gint32 InterlockedAdd(volatile gint32 *dest, gint32 add)
+{
+ return InterlockedExchangeAdd (dest, add) + add;
+}
+#endif
+
+#if defined(_MSC_VER) && !defined(InterlockedAdd64)
+#if defined(InterlockedExchangeAdd64)
+/* This may be defined only on amd64 */
+static inline gint64 InterlockedAdd64(volatile gint64 *dest, gint64 add)
+{
+ return InterlockedExchangeAdd64 (dest, add) + add;
+}
+#else
+static inline gint64 InterlockedAdd64(volatile gint64 *dest, gint64 add)
+{
+ gint64 prev_value;
+
+ do {
+ prev_value = *dest;
+ } while (prev_value != InterlockedCompareExchange64(dest, prev_value + add, prev_value));
+
+ return prev_value + add;
+}
+#endif
+#endif
+
/* And now for some dirty hacks... The Windows API doesn't
* provide any useful primitives for this (other than getting
* into architecture-specific madness), so use CAS. */