Bug 707469 - Don't use UNIX variant xptcinvoke implementation on mingw r=benjamin
authorJacek Caban <jacek@codeweavers.com>
Thu, 15 Dec 2011 17:14:34 +0100
changeset 82661 d744d9200a0b1437a3f67a811ca3ac68e4886d4a
parent 82660 2dcafeb76514fb00e9318eb8f8e2eef778b60721
child 82663 87d2de8f7db7bfaef1f84ec3e0316a23c2a72ddf
push id4045
push userjacek@codeweavers.com
push dateThu, 15 Dec 2011 16:16:02 +0000
treeherdermozilla-inbound@d744d9200a0b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbenjamin
bugs707469
milestone11.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 707469 - Don't use UNIX variant xptcinvoke implementation on mingw r=benjamin
xpcom/reflect/xptcall/src/md/unix/xptc_gcc_x86_unix.h
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_gcc_x86_unix.cpp
xpcom/reflect/xptcall/src/md/win32/Makefile.in
xpcom/reflect/xptcall/src/md/win32/xptcinvoke_x86_gnu.cpp
--- a/xpcom/reflect/xptcall/src/md/unix/xptc_gcc_x86_unix.h
+++ b/xpcom/reflect/xptcall/src/md/unix/xptc_gcc_x86_unix.h
@@ -36,24 +36,16 @@
  * ***** END LICENSE BLOCK ***** */
 
 /* Special include file for xptc*_gcc_x86_unix.cpp */
 
 // 
 // this may improve the static function calls, but may not.
 //
 
-// #define MOZ_USE_STDCALL
-
-#ifdef MOZ_USE_STDCALL
-#define ATTRIBUTE_STDCALL __attribute__ ((__stdcall__))
-#else
-#define ATTRIBUTE_STDCALL
-#endif
-
 #ifdef MOZ_NEED_LEADING_UNDERSCORE
 #define SYMBOL_UNDERSCORE "_"
 #else
 #define SYMBOL_UNDERSCORE
 #endif
 
 
 #define ATTRIBUTE_USED __attribute__ ((__used__))
--- a/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_gcc_x86_unix.cpp
+++ b/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_gcc_x86_unix.cpp
@@ -37,20 +37,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 /* Platform specific code to invoke XPCOM methods on native objects */
 
 #include "xptcprivate.h"
 #include "xptc_gcc_x86_unix.h"
 
 extern "C" {
-#ifndef XP_WIN32
-static
-#endif
-void ATTRIBUTE_USED __attribute__ ((regparm(3)))
+static void ATTRIBUTE_USED __attribute__ ((regparm(3)))
 invoke_copy_to_stack(PRUint32 paramCount, nsXPTCVariant* s, PRUint32* d)
 {
     for(PRUint32 i = paramCount; i >0; i--, d++, s++)
     {
         if(s->IsPtrData())
         {
             *((void**)d) = s->ptr;
             continue;
@@ -84,17 +81,17 @@ invoke_copy_to_stack(PRUint32 paramCount
 */
 
 __asm__ (
 	".text\n\t"
 /* alignment here seems unimportant here; this was 16, now it's 2 which
    is what xptcstubs uses. */
 	".align 2\n\t"
 	".globl " SYMBOL_UNDERSCORE "NS_InvokeByIndex_P\n\t"
-#if !defined(XP_WIN32) && !defined(XP_OS2) && !defined(XP_MACOSX)
+#ifndef XP_MACOSX
 	".type  " SYMBOL_UNDERSCORE "NS_InvokeByIndex_P,@function\n"
 #endif
 	SYMBOL_UNDERSCORE "NS_InvokeByIndex_P:\n\t"
 	"pushl %ebp\n\t"
 	"movl  %esp, %ebp\n\t"
 	"movl  0x10(%ebp), %eax\n\t"
 	"leal  0(,%eax,8),%edx\n\t"
 
@@ -122,16 +119,12 @@ invoke_copy_to_stack(PRUint32 paramCount
 	"movl  0x08(%ebp), %ecx\n\t"	/* 'that' */
 	"movl  (%ecx), %edx\n\t"
 	"movl  0x0c(%ebp), %eax\n\t"    /* function index */
 	"leal  (%edx,%eax,4), %edx\n\t"
 	"call  *(%edx)\n\t"
 	"movl  %ebp, %esp\n\t"
 	"popl  %ebp\n\t"
 	"ret\n"
-#if defined(XP_WIN32) || defined(XP_OS2)
-	".section .drectve\n\t"
-	".ascii \" -export:NS_InvokeByIndex_P\"\n\t"
-	".text\n\t"
-#elif !defined(XP_MACOSX)
+#ifndef XP_MACOSX
 	".size " SYMBOL_UNDERSCORE "NS_InvokeByIndex_P, . -" SYMBOL_UNDERSCORE "NS_InvokeByIndex_P\n\t"
 #endif
 );
--- a/xpcom/reflect/xptcall/src/md/win32/Makefile.in
+++ b/xpcom/reflect/xptcall/src/md/win32/Makefile.in
@@ -42,54 +42,42 @@ VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= xpcom
 LIBRARY_NAME	= xptcmd
 EXPORT_LIBRARY	= ../..
 MOZILLA_INTERNAL_API = 1
 
-#
-# The default is this buildable, but non-functioning code.
-#
-ifdef GNU_CXX
-CPPSRCS		= \
-		../unix/xptcinvoke_gcc_x86_unix.cpp \
-		xptcstubs.cpp \
-		$(NULL)
-LOCAL_INCLUDES	= -I$(srcdir)/../unix
-ifneq ($(TARGET_CPU),x86_64)
-DEFINES		+= -DMOZ_USE_STDCALL -DMOZ_NEED_LEADING_UNDERSCORE
-endif
-else
-
-ifneq ($(OS_TEST),x86_64)
-# FIXME: bug 413019
-OS_COMPILE_CXXFLAGS += -GL-
-endif
-
-CPPSRCS		= xptcinvoke.cpp xptcstubs.cpp
-
-endif
-
-
 LOCAL_INCLUDES += -I$(srcdir)/../../../../xptinfo/src
 
 
 include $(topsrcdir)/config/config.mk
 
-ifeq ($(TARGET_CPU),x86_64)
+ifneq ($(TARGET_CPU),x86_64)
+
 ifndef GNU_CXX
-CPPSRCS 	:= xptcinvoke_x86_64.cpp xptcstubs_x86_64.cpp
+# FIXME: bug 413019
+OS_COMPILE_CXXFLAGS += -GL-
+CPPSRCS         := xptcinvoke.cpp xptcstubs.cpp
+else  #!GNU_CXX
+CPPSRCS         := xptcinvoke_x86_gnu.cpp xptcstubs.cpp
+endif #!GNU_CXX
+
+else # !x86_64
+
+ifndef GNU_CXX
+CPPSRCS		:= xptcinvoke_x86_64.cpp xptcstubs_x86_64.cpp
 ASFILES		:= xptcinvoke_asm_x86_64.asm xptcstubs_asm_x86_64.asm
 else #!GNU_CXX
-CPPSRCS		:= xptcinvoke_x86_64.cpp  xptcstubs_x86_64_gnu.cpp
+CPPSRCS		:= xptcinvoke_x86_64.cpp xptcstubs_x86_64_gnu.cpp
 ASFILES		:= xptcinvoke_asm_x86_64_gnu.s
 endif #!GNU_CXX
-endif
+
+endif #!x86_64
 
 # we don't want the shared lib, but we want to force the creation of a static lib.
 FORCE_STATIC_LIB = 1
 
 include $(topsrcdir)/config/rules.mk
 
 DEFINES		+= -DEXPORT_XPTC_API -D_IMPL_NS_COM
 
new file mode 100644
--- /dev/null
+++ b/xpcom/reflect/xptcall/src/md/win32/xptcinvoke_x86_gnu.cpp
@@ -0,0 +1,139 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Mark Mentovai <mark@moxienet.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* Platform specific code to invoke XPCOM methods on native objects */
+
+#include "xptcprivate.h"
+
+extern "C" {
+void __attribute__ ((__used__)) __attribute__ ((regparm(3)))
+invoke_copy_to_stack(PRUint32 paramCount, nsXPTCVariant* s, PRUint32* d)
+{
+    for(PRUint32 i = paramCount; i >0; i--, d++, s++)
+    {
+        if(s->IsPtrData())
+        {
+            *((void**)d) = s->ptr;
+            continue;
+        }
+
+        switch(s->type)
+        {
+        case nsXPTType::T_I8     : *((PRInt8*)  d) = s->val.i8;          break;
+        case nsXPTType::T_I16    : *((PRInt16*) d) = s->val.i16;         break;
+        case nsXPTType::T_I32    : *((PRInt32*) d) = s->val.i32;         break;
+        case nsXPTType::T_I64    : *((PRInt64*) d) = s->val.i64; d++;    break;
+        case nsXPTType::T_U8     : *((PRUint8*) d) = s->val.u8;          break;
+        case nsXPTType::T_U16    : *((PRUint16*)d) = s->val.u16;         break;
+        case nsXPTType::T_U32    : *((PRUint32*)d) = s->val.u32;         break;
+        case nsXPTType::T_U64    : *((PRUint64*)d) = s->val.u64; d++;    break;
+        case nsXPTType::T_FLOAT  : *((float*)   d) = s->val.f;           break;
+        case nsXPTType::T_DOUBLE : *((double*)  d) = s->val.d;   d++;    break;
+        case nsXPTType::T_BOOL   : *((bool*)    d) = s->val.b;           break;
+        case nsXPTType::T_CHAR   : *((char*)    d) = s->val.c;           break;
+        case nsXPTType::T_WCHAR  : *((wchar_t*) d) = s->val.wc;          break;
+        default:
+            // all the others are plain pointer types
+            *((void**)d) = s->val.p;
+            break;
+        }
+    }
+}
+} // extern "C"
+
+/*
+  EXPORT_XPCOM_API(nsresult)
+  NS_InvokeByIndex_P(nsISupports* that, PRUint32 methodIndex,
+                   PRUint32 paramCount, nsXPTCVariant* params);
+
+  Each param takes at most two 4-byte words.
+  It doesn't matter if we push too many words, and calculating the exact
+  amount takes time.
+
+  that        = ebp + 0x08
+  methodIndex = ebp + 0x0c
+  paramCount  = ebp + 0x10
+  params      = ebp + 0x14
+
+*/
+
+__asm__ (
+	".text\n\t"
+/* alignment here seems unimportant here; this was 16, now it's 2 which
+   is what xptcstubs uses. */
+	".align 2\n\t"
+	".globl _NS_InvokeByIndex_P\n\t"
+	"_NS_InvokeByIndex_P:\n\t"
+	"pushl %ebp\n\t"
+	"movl  %esp, %ebp\n\t"
+	"movl  0x10(%ebp), %eax\n\t"
+	"leal  0(,%eax,8),%edx\n\t"
+
+        /* set up call frame for method. */
+	"subl  %edx, %esp\n\t"       /* make room for params. */
+/* Align to maximum x86 data size: 128 bits == 16 bytes == XMM register size.
+ * This is to avoid protection faults where SSE+ alignment of stack pointer
+ * is assumed and required, e.g. by GCC4's -ftree-vectorize option.
+ */
+	"andl  $0xfffffff0, %esp\n\t"   /* drop(?) stack ptr to 128-bit align */
+/* $esp should be aligned to a 16-byte boundary here (note we include an 
+ * additional 4 bytes in a later push instruction). This will ensure $ebp 
+ * in the function called below is aligned to a 0x8 boundary. SSE instructions 
+ * like movapd/movdqa expect memory operand to be aligned on a 16-byte
+ * boundary. The GCC compiler will generate the memory operand using $ebp
+ * with an 8-byte offset.
+ */
+	"subl  $0xc, %esp\n\t"          /* lower again; push/call below will re-align */
+	"movl  %esp, %ecx\n\t"          /* ecx = d */
+	"movl  8(%ebp), %edx\n\t"       /* edx = this */
+	"pushl %edx\n\t"                /* push this. esp % 16 == 0 */
+
+	"movl  0x14(%ebp), %edx\n\t"
+	"call  _invoke_copy_to_stack\n\t"
+	"movl  0x08(%ebp), %ecx\n\t"	/* 'that' */
+	"movl  (%ecx), %edx\n\t"
+	"movl  0x0c(%ebp), %eax\n\t"    /* function index */
+	"leal  (%edx,%eax,4), %edx\n\t"
+	"call  *(%edx)\n\t"
+	"movl  %ebp, %esp\n\t"
+	"popl  %ebp\n\t"
+	"ret\n"
+	".section .drectve\n\t"
+	".ascii \" -export:NS_InvokeByIndex_P\"\n\t"
+	".text\n\t"
+);