77 lines
3.6 KiB
Diff
77 lines
3.6 KiB
Diff
# HG changeset patch
|
|
# User L. David Baron <dbaron@dbaron.org>
|
|
# Date 1423526165 -39600
|
|
# Tue Feb 10 10:56:05 2015 +1100
|
|
# Node ID bb794f1592545807ddbb56b4dc0392bf180ffade
|
|
# Parent cba00af659930c70eb5940e230950e3ead0f9e12
|
|
Bug 680547 - Compile Linux 64-bit NS_InvokeByIndex with -mno-avx to allow compiling with -march=native on new hardware, or similar -march flags.
|
|
|
|
As explained in bug 1111355, having avx enabled appears to change the
|
|
alignment behavior of alloca (apparently adding an extra 16 bytes) of
|
|
padding/alignment (and using 32-byte alignment instead of 16-byte). The
|
|
suggestion of using __bultin_alloca_with_align in bug 1111355 didn't fix
|
|
the problem, so this seems to be the best available workaround, given
|
|
that this code, which should perhaps better be written in assembly, is
|
|
written in C++.
|
|
|
|
Interestingly, this is NOT fixed by #pragma GCC target ("arch=x86-64").
|
|
(I determined the (undocumented) name for the default -march value on
|
|
x86_64 from the gcc source code (gcc/config/i386/i386.c, function
|
|
ix86_option_override_internal, code that sets opts->x_ix86_arch_string .)
|
|
I confirmed that this sets the same macros based on the empty diff
|
|
between the output of 'gcc -E -dM -x c++ /dev/null' and 'gcc -E -dM -x
|
|
c++ -march=x86-64 /dev/null', which was not an empty diff for other
|
|
-march values (e.g., k8).)
|
|
|
|
I confirmed that the push_options and pop_options actually work by
|
|
putting the push/pop pair around a different (earlier) function, and
|
|
testing that this did not fix the bug (with the pop_options before
|
|
NS_InvokeByIndex).
|
|
|
|
See the gcc documentation at:
|
|
https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/Function-Specific-Option-Pragmas.html
|
|
https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/Function-Attributes.html
|
|
https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/i386-and-x86-64-Options.html
|
|
|
|
diff --git a/xpcom/reflect/xptcall/md/unix/xptcinvoke_x86_64_unix.cpp b/xpcom/reflect/xptcall/md/unix/xptcinvoke_x86_64_unix.cpp
|
|
--- a/xpcom/reflect/xptcall/md/unix/xptcinvoke_x86_64_unix.cpp
|
|
+++ b/xpcom/reflect/xptcall/md/unix/xptcinvoke_x86_64_unix.cpp
|
|
@@ -96,16 +96,26 @@ invoke_copy_to_stack(uint64_t * d, uint3
|
|
if (nr_gpr < GPR_COUNT)
|
|
gpregs[nr_gpr++] = value;
|
|
else
|
|
*d++ = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
+// Disable avx for the next function to allow compilation with
|
|
+// -march=native on new machines, or similar hardcoded -march options.
|
|
+// Having avx enabled appears to change the alignment behavior of alloca
|
|
+// (apparently adding an extra 16 bytes) of padding/alignment (and using
|
|
+// 32-byte alignment instead of 16-byte). This seems to be the best
|
|
+// available workaround, given that this code, which should perhaps
|
|
+// better be written in assembly, is written in C++.
|
|
+#pragma GCC push_options
|
|
+#pragma GCC target ("no-avx")
|
|
+
|
|
EXPORT_XPCOM_API(nsresult)
|
|
NS_InvokeByIndex(nsISupports * that, uint32_t methodIndex,
|
|
uint32_t paramCount, nsXPTCVariant * params)
|
|
{
|
|
uint32_t nr_stack;
|
|
invoke_count_words(paramCount, params, nr_stack);
|
|
|
|
// Stack, if used, must be 16-bytes aligned
|
|
@@ -159,8 +169,10 @@ NS_InvokeByIndex(nsISupports * that, uin
|
|
typedef nsresult (*Method)(uint64_t, uint64_t, uint64_t, uint64_t,
|
|
uint64_t, uint64_t, double, double, double,
|
|
double, double, double, double, double);
|
|
nsresult result = ((Method)methodAddress)(a0, a1, a2, a3, a4, a5,
|
|
d0, d1, d2, d3, d4, d5,
|
|
d6, d7);
|
|
return result;
|
|
}
|
|
+
|
|
+#pragma GCC pop_options
|