diff options
Diffstat (limited to 'xpcom')
-rw-r--r-- | xpcom/base/nsDebugImpl.cpp | 8 | ||||
-rw-r--r-- | xpcom/base/nsMemoryReporterManager.cpp | 83 | ||||
-rw-r--r-- | xpcom/base/nsTraceRefcnt.cpp | 2 | ||||
-rw-r--r-- | xpcom/ds/nsMathUtils.h | 5 | ||||
-rw-r--r-- | xpcom/glue/FileUtils.cpp | 2 | ||||
-rw-r--r-- | xpcom/io/nsLocalFileUnix.cpp | 16 | ||||
-rw-r--r-- | xpcom/reflect/xptcall/md/unix/moz.build | 32 | ||||
-rw-r--r-- | xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_sparc_solaris_GCC3.s | 52 | ||||
-rw-r--r-- | xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_x86_64_unix.S | 122 | ||||
-rw-r--r-- | xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc64_openbsd.cpp | 4 | ||||
-rw-r--r-- | xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc_solaris.cpp | 141 | ||||
-rw-r--r-- | xpcom/reflect/xptcall/md/unix/xptcinvoke_x86_64_solaris.cpp | 75 | ||||
-rw-r--r-- | xpcom/reflect/xptcall/md/unix/xptcstubs_asm_sparc_solaris.s | 49 | ||||
-rw-r--r-- | xpcom/reflect/xptcall/md/unix/xptcstubs_sparc64_openbsd.cpp | 7 | ||||
-rw-r--r-- | xpcom/reflect/xptcall/md/unix/xptcstubs_sparc_solaris.cpp | 112 | ||||
-rw-r--r-- | xpcom/reflect/xptcall/status.html | 14 | ||||
-rw-r--r-- | xpcom/string/nsTSubstring.h | 19 | ||||
-rw-r--r-- | xpcom/threads/nsThreadPool.cpp | 4 |
18 files changed, 740 insertions, 7 deletions
diff --git a/xpcom/base/nsDebugImpl.cpp b/xpcom/base/nsDebugImpl.cpp index a81eb3d71..84ba150db 100644 --- a/xpcom/base/nsDebugImpl.cpp +++ b/xpcom/base/nsDebugImpl.cpp @@ -450,6 +450,12 @@ RealBreak() ".object_arch armv4t\n" #endif "BKPT #0"); +#elif defined(__sun) +#if defined (__i386__) || defined(__i386) || defined(__x86_64__) + asm("int $3"); +#else + raise(SIGTRAP); +#endif #else #warning do not know how to break on this platform #endif @@ -524,6 +530,8 @@ Break(const char* aMsg) RealBreak(); #elif defined(__arm__) RealBreak(); +#elif defined(__sun) + RealBreak(); #else #warning do not know how to break on this platform #endif diff --git a/xpcom/base/nsMemoryReporterManager.cpp b/xpcom/base/nsMemoryReporterManager.cpp index 88964f9b5..dcbad171e 100644 --- a/xpcom/base/nsMemoryReporterManager.cpp +++ b/xpcom/base/nsMemoryReporterManager.cpp @@ -317,6 +317,85 @@ VsizeMaxContiguousDistinguishedAmount(int64_t* aN) } #endif // FreeBSD +#elif defined(XP_SOLARIS) + +#include <procfs.h> +#include <fcntl.h> +#include <unistd.h> + +static void +XMappingIter(int64_t& aVsize, int64_t& aResident) +{ + aVsize = -1; + aResident = -1; + int mapfd = open("/proc/self/xmap", O_RDONLY); + struct stat st; + prxmap_t* prmapp = nullptr; + if (mapfd >= 0) { + if (!fstat(mapfd, &st)) { + int nmap = st.st_size / sizeof(prxmap_t); + while (1) { + // stat(2) on /proc/<pid>/xmap returns an incorrect value, + // prior to the release of Solaris 11. + // Here is a workaround for it. + nmap *= 2; + prmapp = (prxmap_t*)malloc((nmap + 1) * sizeof(prxmap_t)); + if (!prmapp) { + // out of memory + break; + } + int n = pread(mapfd, prmapp, (nmap + 1) * sizeof(prxmap_t), 0); + if (n < 0) { + break; + } + if (nmap >= n / sizeof(prxmap_t)) { + aVsize = 0; + aResident = 0; + for (int i = 0; i < n / sizeof(prxmap_t); i++) { + aVsize += prmapp[i].pr_size; + aResident += prmapp[i].pr_rss * prmapp[i].pr_pagesize; + } + break; + } + free(prmapp); + } + free(prmapp); + } + close(mapfd); + } +} + +#define HAVE_VSIZE_AND_RESIDENT_REPORTERS 1 +static MOZ_MUST_USE nsresult +VsizeDistinguishedAmount(int64_t* aN) +{ + int64_t vsize, resident; + XMappingIter(vsize, resident); + if (vsize == -1) { + return NS_ERROR_FAILURE; + } + *aN = vsize; + return NS_OK; +} + +static MOZ_MUST_USE nsresult +ResidentDistinguishedAmount(int64_t* aN) +{ + int64_t vsize, resident; + XMappingIter(vsize, resident); + if (resident == -1) { + return NS_ERROR_FAILURE; + } + *aN = resident; + return NS_OK; +} + +static MOZ_MUST_USE nsresult +ResidentFastDistinguishedAmount(int64_t* aN) +{ + return ResidentDistinguishedAmount(aN); +} + #elif defined(XP_MACOSX) #include <mach/mach_init.h> @@ -1066,9 +1145,13 @@ ResidentPeakDistinguishedAmount(int64_t* aN) if (0 == getrusage(RUSAGE_SELF, &usage)) { // The units for ru_maxrrs: // - Mac: bytes + // - Solaris: pages? But some sources it actually always returns 0, so + // check for that // - Linux, {Net/Open/Free}BSD, DragonFly: KiB #ifdef XP_MACOSX *aN = usage.ru_maxrss; +#elif defined(XP_SOLARIS) + *aN = usage.ru_maxrss * getpagesize(); #else *aN = usage.ru_maxrss * 1024; #endif diff --git a/xpcom/base/nsTraceRefcnt.cpp b/xpcom/base/nsTraceRefcnt.cpp index da51305a9..48448dbd9 100644 --- a/xpcom/base/nsTraceRefcnt.cpp +++ b/xpcom/base/nsTraceRefcnt.cpp @@ -657,7 +657,7 @@ InitLog(const char* aEnvVar, const char* aMsg, FILE** aResult) fname.Append('_'); fname.Append((char*)XRE_ChildProcessTypeToString(XRE_GetProcessType())); fname.AppendLiteral("_pid"); - fname.AppendInt((uint32_t)getpid()); + fname.AppendInt(getpid()); if (hasLogExtension) { fname.AppendLiteral(".log"); } diff --git a/xpcom/ds/nsMathUtils.h b/xpcom/ds/nsMathUtils.h index cbbd38611..e3f423c8f 100644 --- a/xpcom/ds/nsMathUtils.h +++ b/xpcom/ds/nsMathUtils.h @@ -11,6 +11,11 @@ #include <cmath> #include <float.h> +#ifdef XP_SOLARIS +#include <math.h> +#include <ieeefp.h> +#endif + /* * round */ diff --git a/xpcom/glue/FileUtils.cpp b/xpcom/glue/FileUtils.cpp index 699812461..53fe68708 100644 --- a/xpcom/glue/FileUtils.cpp +++ b/xpcom/glue/FileUtils.cpp @@ -532,7 +532,7 @@ mozilla::ReadAheadFile(mozilla::pathstr_t aFilePath, const size_t aOffset, if (!aOutFd) { CloseHandle(fd); } -#elif defined(LINUX) && !defined(ANDROID) || defined(XP_MACOSX) +#elif defined(LINUX) && !defined(ANDROID) || defined(XP_MACOSX) || defined(XP_SOLARIS) if (!aFilePath) { if (aOutFd) { *aOutFd = -1; diff --git a/xpcom/io/nsLocalFileUnix.cpp b/xpcom/io/nsLocalFileUnix.cpp index 272153bba..06706235d 100644 --- a/xpcom/io/nsLocalFileUnix.cpp +++ b/xpcom/io/nsLocalFileUnix.cpp @@ -1591,6 +1591,22 @@ nsLocalFile::IsExecutable(bool* aResult) // Then check the execute bit. *aResult = (access(mPath.get(), X_OK) == 0); +#ifdef XP_SOLARIS + // On Solaris, access will always return 0 for root user, however + // the file is only executable if S_IXUSR | S_IXGRP | S_IXOTH is set. + // See bug 351950, https://bugzilla.mozilla.org/show_bug.cgi?id=351950 + if (*aResult) { + struct STAT buf; + + *aResult = (STAT(mPath.get(), &buf) == 0); + if (*aResult || errno == EACCES) { + *aResult = *aResult && (buf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)); + return NS_OK; + } + + return NSRESULT_FOR_ERRNO(); + } +#endif if (*aResult || errno == EACCES) { return NS_OK; } diff --git a/xpcom/reflect/xptcall/md/unix/moz.build b/xpcom/reflect/xptcall/md/unix/moz.build index d455ed854..8ee7b3181 100644 --- a/xpcom/reflect/xptcall/md/unix/moz.build +++ b/xpcom/reflect/xptcall/md/unix/moz.build @@ -46,6 +46,21 @@ if CONFIG['OS_ARCH'] in ('Linux', 'FreeBSD'): 'xptcstubs_ipf64.cpp' ] +# Without the need to accomodate the Sun compiler, Solaris/GCC support is pretty +# standard, actually. Not all that different from Linux. + +if CONFIG['OS_ARCH'] == 'SunOS': + if CONFIG['OS_TEST'] == 'x86_64': + SOURCES += [ + 'xptcinvoke_asm_x86_64_unix.S', + 'xptcinvoke_x86_64_solaris.cpp', + 'xptcstubs_x86_64_linux.cpp' + ] + elif '86' in CONFIG['OS_TEST']: + SOURCES += [ + 'xptcinvoke_gcc_x86_unix.cpp', + 'xptcstubs_gcc_x86_unix.cpp' + ] if CONFIG['OS_TEST'] == 'alpha': if CONFIG['OS_ARCH'] in ('Linux', 'FreeBSD', 'NetBSD'): @@ -186,7 +201,11 @@ if CONFIG['OS_ARCH'] == 'OpenBSD' and CONFIG['OS_TEST'] == 'sparc': 'xptcstubs_sparc_openbsd.cpp', ] -if CONFIG['OS_ARCH'] in ('OpenBSD', 'FreeBSD') and CONFIG['OS_TEST'] == 'sparc64': +# Mozilla discovered at some point that Solaris and Linux can also use these +# files for 64-bit SPARC with no ill effects, so basically the entire mess that +# was there before is no longer needed. + +if CONFIG['OS_ARCH'] in ('OpenBSD', 'FreeBSD', 'SunOS') and CONFIG['OS_TEST'] == 'sparc64': SOURCES += [ 'xptcinvoke_asm_sparc64_openbsd.s', 'xptcinvoke_sparc64_openbsd.cpp', @@ -194,6 +213,17 @@ if CONFIG['OS_ARCH'] in ('OpenBSD', 'FreeBSD') and CONFIG['OS_TEST'] == 'sparc64 'xptcstubs_sparc64_openbsd.cpp', ] +# As for the 32-bit SPARC build? That would look like the Linux version with +# one file changed. + +if CONFIG['OS_ARCH'] == 'SunOS' and CONFIG['OS_TEST'] == 'sparc': + SOURCES += [ + 'xptcinvoke_asm_sparc_solaris_GCC3.s', + 'xptcinvoke_sparc_solaris.cpp', + 'xptcstubs_asm_sparc_solaris.s', + 'xptcstubs_sparc_solaris.cpp', + ] + if CONFIG['OS_ARCH'] == 'Linux': if CONFIG['OS_TEST'] == 's390': SOURCES += [ diff --git a/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_sparc_solaris_GCC3.s b/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_sparc_solaris_GCC3.s new file mode 100644 index 000000000..54adcd147 --- /dev/null +++ b/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_sparc_solaris_GCC3.s @@ -0,0 +1,52 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Platform specific code to invoke XPCOM methods on native objects for + * solaris/sparc with gcc 3 ABI. + */ + .global NS_InvokeByIndex +/* + * NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex, + * uint32_t paramCount, nsXPTCVariant* params); + */ +NS_InvokeByIndex: + save %sp,-(64 + 32),%sp ! room for the register window and + ! struct pointer, rounded up to 0 % 32 + mov %i2,%o0 ! paramCount + call invoke_count_words ! returns the required stack size in %o0 + mov %i3,%o1 ! params + + sll %o0,2,%l0 ! number of bytes + sub %sp,%l0,%sp ! create the additional stack space + + mov %sp,%o0 ! pointer for copied args + add %o0,72,%o0 ! step past the register window, the + ! struct result pointer and the 'this' slot + mov %i2,%o1 ! paramCount + call invoke_copy_to_stack + mov %i3,%o2 ! params +! +! calculate the target address from the vtable +! + ld [%i0],%l1 ! *that --> vTable + sll %i1,2,%i1 ! multiply index by 4 + add %i1,%l1,%l1 ! l1 now points to vTable entry + ld [%l1],%l0 ! target address + +.L5: ld [%sp + 88],%o5 +.L4: ld [%sp + 84],%o4 +.L3: ld [%sp + 80],%o3 +.L2: ld [%sp + 76],%o2 +.L1: ld [%sp + 72],%o1 +.L0: + jmpl %l0,%o7 ! call the routine +! always have a 'this', from the incoming 'that' + mov %i0,%o0 + + mov %o0,%i0 ! propagate return value + ret + restore diff --git a/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_x86_64_unix.S b/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_x86_64_unix.S new file mode 100644 index 000000000..131cfc334 --- /dev/null +++ b/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_x86_64_unix.S @@ -0,0 +1,122 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Darwin gives a leading '_' to symbols defined in C code. +#ifdef XP_DARWIN +#define SYM(x) _ ## x +#define CFI_STARTPROC +#define CFI_ENDPROC +#define CFI_DEF_CFA_OFFSET(offset) +#define CFI_OFFSET(reg, offset) +#define CFI_DEF_CFA_REGISTER(reg) +#define CFI_DEF_CFA(reg, offset) +#else +#define SYM(x) x +#define CFI_STARTPROC .cfi_startproc +#define CFI_ENDPROC .cfi_endproc +#define CFI_DEF_CFA_OFFSET(offset) .cfi_def_cfa_offset offset +#define CFI_OFFSET(reg, offset) .cfi_offset reg, offset +#define CFI_DEF_CFA_REGISTER(reg) .cfi_def_cfa_register reg +#define CFI_DEF_CFA(reg, offset) .cfi_def_cfa reg, offset +#endif + +.intel_syntax noprefix + +# nsresult NS_InvokeByIndex(nsISupports* this, uint32_t aVtableIndex, +# uint32_t argc, nsXPTCVariant* argv); +.text +.global SYM(NS_InvokeByIndex) +#ifndef XP_DARWIN +.type NS_InvokeByIndex, @function +#endif +.align 4 +SYM(NS_InvokeByIndex): + CFI_STARTPROC + push rbp + CFI_DEF_CFA_OFFSET(16) + CFI_OFFSET(6, -16) + mov rbp, rsp + CFI_DEF_CFA_REGISTER(6) + +# save r12 and r13 because we use them and they are callee saved. + push r12 + push r13 + CFI_OFFSET(12, -24) + CFI_OFFSET(13, -32) + +# save this and the vtable index because we need them after setting up the +# stack. + mov r12, rdi + mov r13, rsi + +# allocate space for stack arguments, in theory we only need 8 * (argc - 5) +# bytes because at least 5 arguments will go in registers, but for now it is +# just simpler to allocate 8 * argc bytes. Note that we treat the this +# pointer specially. + lea eax, [edx * 8] + sub rsp, rax + +# If there is an odd number of args the stack can be misaligned so realign it. + and rsp, 0xfffffffffffffff0 + +# pass the stack slot area to InvokeCopyToStack. + mov r8, rsp + +# setup space for the register slots: there are 5 integer ones and 8 floating +# point ones. So we need 104 bytes of space, but we allocate 112 to keep rsp +# aligned to 16 bytes. + sub rsp, 112 + +# the first argument to InvokeCopyToStack is the integer register area, and the +# second is the floating point area. + mov rdi, rsp + lea rsi, [rsp + 40] + +# The 3rd and 4th arguments to InvokeCopyToStack are already in the right +# registers. So now we can just call InvokeCopyToStack. + call SYM(InvokeCopyToStack) + +# setup this + mov rdi, r12 + +# copy the integer arguments into place. + mov rsi, [rsp] + mov rdx, [rsp + 8] + mov rcx, [rsp + 16] + mov r8, [rsp + 24] + mov r9, [rsp + 32] + +# copy the float arguments into place + movsd xmm0, [rsp + 40] + movsd xmm1, [rsp + 48] + movsd xmm2, [rsp + 56] + movsd xmm3, [rsp + 64] + movsd xmm4, [rsp + 72] + movsd xmm5, [rsp + 80] + movsd xmm6, [rsp + 88] + movsd xmm7, [rsp + 96] + +# get rid of the scratch space for registers + add rsp, 112 + +# load the function pointer and call + lea eax, [r13d * 8] + add rax, [rdi] + call [rax] + +# r12 and r13 were pushed relative to the old stack pointer which is now the +# frame pointer. + mov r12, [rbp - 0x8] + mov r13, [rbp - 0x10] + + mov rsp, rbp + pop rbp + CFI_DEF_CFA(7, 8) + ret + CFI_ENDPROC + +#ifndef XP_DARWIN +// Magic indicating no need for an executable stack +.section .note.GNU-stack, "", @progbits ; .previous +#endif diff --git a/xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc64_openbsd.cpp b/xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc64_openbsd.cpp index 050f9414d..1b5039ed9 100644 --- a/xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc64_openbsd.cpp +++ b/xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc64_openbsd.cpp @@ -30,9 +30,9 @@ invoke_copy_to_stack(uint64_t* d, uint32_t paramCount, nsXPTCVariant* s) { if (regCount < 5) regCount++; - if (l_s->IsPtrData()) + if (l_s->IsIndirect()) { - *l_d = (uint64_t)l_s->ptr; + *l_d = (uint64_t) &l_s->val; continue; } switch (l_s->type) diff --git a/xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc_solaris.cpp b/xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc_solaris.cpp new file mode 100644 index 000000000..c1b679779 --- /dev/null +++ b/xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc_solaris.cpp @@ -0,0 +1,141 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + +#include "xptcprivate.h" + +/* solaris defines __sparc for workshop compilers and + linux defines __sparc__ */ + +#if !defined(__sparc) && !defined(__sparc__) +#error "This code is for Sparc only" +#endif + +typedef unsigned nsXPCVariant; + +extern "C" uint32_t +invoke_count_words(uint32_t paramCount, nsXPTCVariant* s) +{ + uint32_t result = 0; + for(uint32_t i = 0; i < paramCount; i++, s++) + { + if(s->IsPtrData()) + { + result++; + continue; + } + switch(s->type) + { + case nsXPTType::T_I8 : + case nsXPTType::T_I16 : + case nsXPTType::T_I32 : + result++; + break; + case nsXPTType::T_I64 : + result+=2; + break; + case nsXPTType::T_U8 : + case nsXPTType::T_U16 : + case nsXPTType::T_U32 : + result++; + break; + case nsXPTType::T_U64 : + result+=2; + break; + case nsXPTType::T_FLOAT : + result++; + break; + case nsXPTType::T_DOUBLE : + result+=2; + break; + case nsXPTType::T_BOOL : + case nsXPTType::T_CHAR : + case nsXPTType::T_WCHAR : + result++; + break; + default: + // all the others are plain pointer types + result++; + break; + } + } + // nuts, I know there's a cooler way of doing this, but it's late + // now and it'll probably come to me in the morning. + if (result & 0x3) result += 4 - (result & 0x3); // ensure q-word alignment + return result; +} + +extern "C" uint32_t +invoke_copy_to_stack(uint32_t* d, uint32_t paramCount, nsXPTCVariant* s) +{ +/* + We need to copy the parameters for this function to locals and use them + from there since the parameters occupy the same stack space as the stack + we're trying to populate. +*/ + uint32_t *l_d = d; + nsXPTCVariant *l_s = s; + uint32_t l_paramCount = paramCount; + uint32_t regCount = 0; // return the number of registers to load from the stack + + typedef struct { + uint32_t hi; + uint32_t lo; + } DU; // have to move 64 bit entities as 32 bit halves since + // stack slots are not guaranteed 16 byte aligned + + for(uint32_t i = 0; i < l_paramCount; i++, l_d++, l_s++) + { + if (regCount < 5) regCount++; + if(l_s->IsPtrData()) + { + if(l_s->type == nsXPTType::T_JSVAL) + { + // On SPARC, we need to pass a pointer to HandleValue + *((void**)l_d) = &l_s->ptr; + } else + { + *((void**)l_d) = l_s->ptr; + } + continue; + } + switch(l_s->type) + { + case nsXPTType::T_I8 : *((int32_t*) l_d) = l_s->val.i8; + break; + case nsXPTType::T_I16 : *((int32_t*) l_d) = l_s->val.i16; + break; + case nsXPTType::T_I32 : *((int32_t*) l_d) = l_s->val.i32; + break; + case nsXPTType::T_I64 : + case nsXPTType::T_U64 : + case nsXPTType::T_DOUBLE : *((uint32_t*) l_d++) = ((DU *)l_s)->hi; + if (regCount < 5) regCount++; + *((uint32_t*) l_d) = ((DU *)l_s)->lo; + break; + case nsXPTType::T_U8 : *((uint32_t*) l_d) = l_s->val.u8; + break; + case nsXPTType::T_U16 : *((uint32_t*) l_d) = l_s->val.u16; + break; + case nsXPTType::T_U32 : *((uint32_t*) l_d) = l_s->val.u32; + break; + case nsXPTType::T_FLOAT : *((float*) l_d) = l_s->val.f; + break; + case nsXPTType::T_BOOL : *((uint32_t*) l_d) = l_s->val.b; + break; + case nsXPTType::T_CHAR : *((uint32_t*) l_d) = l_s->val.c; + break; + case nsXPTType::T_WCHAR : *((int32_t*) l_d) = l_s->val.wc; + break; + default: + // all the others are plain pointer types + *((void**)l_d) = l_s->val.p; + break; + } + } + return regCount; +} + diff --git a/xpcom/reflect/xptcall/md/unix/xptcinvoke_x86_64_solaris.cpp b/xpcom/reflect/xptcall/md/unix/xptcinvoke_x86_64_solaris.cpp new file mode 100644 index 000000000..a9db2a693 --- /dev/null +++ b/xpcom/reflect/xptcall/md/unix/xptcinvoke_x86_64_solaris.cpp @@ -0,0 +1,75 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Platform specific code to invoke XPCOM methods on native objects + +#include "xptcprivate.h" + +// 6 integral parameters are passed in registers, but 1 is |this| which isn't +// considered here. +const uint32_t GPR_COUNT = 5; + +// 8 floating point parameters are passed in SSE registers +const uint32_t FPR_COUNT = 8; + +extern "C" void +InvokeCopyToStack(uint64_t * gpregs, double * fpregs, + uint32_t paramCount, nsXPTCVariant * s, + uint64_t* d) +{ + uint32_t nr_gpr = 0u; // skip one GP register for 'that' + uint32_t nr_fpr = 0u; + uint64_t value = 0u; + + for (uint32_t i = 0; i < paramCount; i++, s++) { + if (s->IsPtrData()) + value = (uint64_t) s->ptr; + else { + switch (s->type) { + case nsXPTType::T_FLOAT: break; + case nsXPTType::T_DOUBLE: break; + case nsXPTType::T_I8: value = s->val.i8; break; + case nsXPTType::T_I16: value = s->val.i16; break; + case nsXPTType::T_I32: value = s->val.i32; break; + case nsXPTType::T_I64: value = s->val.i64; break; + case nsXPTType::T_U8: value = s->val.u8; break; + case nsXPTType::T_U16: value = s->val.u16; break; + case nsXPTType::T_U32: value = s->val.u32; break; + case nsXPTType::T_U64: value = s->val.u64; break; + case nsXPTType::T_BOOL: value = s->val.b; break; + case nsXPTType::T_CHAR: value = s->val.c; break; + case nsXPTType::T_WCHAR: value = s->val.wc; break; + default: value = (uint64_t) s->val.p; break; + } + } + + if (!s->IsPtrData() && s->type == nsXPTType::T_DOUBLE) { + if (nr_fpr < FPR_COUNT) + fpregs[nr_fpr++] = s->val.d; + else { + *((double *)d) = s->val.d; + d++; + } + } + else if (!s->IsPtrData() && s->type == nsXPTType::T_FLOAT) { + if (nr_fpr < FPR_COUNT) + // The value in %xmm register is already prepared to + // be retrieved as a float. Therefore, we pass the + // value verbatim, as a double without conversion. + fpregs[nr_fpr++] = s->val.d; + else { + *((float *)d) = s->val.f; + d++; + } + } + else { + if (nr_gpr < GPR_COUNT) + gpregs[nr_gpr++] = value; + else + *d++ = value; + } + } +} diff --git a/xpcom/reflect/xptcall/md/unix/xptcstubs_asm_sparc_solaris.s b/xpcom/reflect/xptcall/md/unix/xptcstubs_asm_sparc_solaris.s new file mode 100644 index 000000000..9b448d7c7 --- /dev/null +++ b/xpcom/reflect/xptcall/md/unix/xptcstubs_asm_sparc_solaris.s @@ -0,0 +1,49 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + .global SharedStub + +/* + in the frame for the function that called SharedStub are the + rest of the parameters we need + +*/ + +SharedStub: +! we don't create a new frame yet, but work within the frame of the calling +! function to give ourselves the other parameters we want + + mov %o0, %o1 ! shuffle the index up to 2nd place + mov %i0, %o0 ! the original 'this' + add %fp, 72, %o2 ! previous stack top adjusted to the first argument slot (beyond 'this') +! save off the original incoming parameters that arrived in +! registers, the ABI guarantees the space for us to do this + st %i1, [%fp + 72] + st %i2, [%fp + 76] + st %i3, [%fp + 80] + st %i4, [%fp + 84] + st %i5, [%fp + 88] +! now we can build our own stack frame + save %sp,-(64 + 32),%sp ! room for the register window and + ! struct pointer, rounded up to 0 % 32 +! our function now appears to have been called +! as SharedStub(nsISupports* that, uint32_t index, uint32_t* args) +! so we can just copy these through + + mov %i0, %o0 + mov %i1, %o1 + mov %i2, %o2 + call PrepareAndDispatch + nop + mov %o0,%i0 ! propagate return value + b .LL1 + nop +.LL1: + ret + restore + + .size SharedStub, .-SharedStub + .type SharedStub, #function diff --git a/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc64_openbsd.cpp b/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc64_openbsd.cpp index b8a09c97e..e28a03794 100644 --- a/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc64_openbsd.cpp +++ b/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc64_openbsd.cpp @@ -85,8 +85,13 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint64_t methodIndex, uint64_t* args) extern "C" nsresult SharedStub(int, int*); +/* + * Avoid GCC stack protector to wipe out imput registers since the compiler + * thinks the function takes no arguments. + */ + #define STUB_ENTRY(n) \ -nsresult nsXPTCStubBase::Stub##n() \ +nsresult __attribute__((__optimize__("no-stack-protector"))) nsXPTCStubBase::Stub##n() \ { \ int dummy; /* defeat tail-call optimization */ \ return SharedStub(n, &dummy); \ diff --git a/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc_solaris.cpp b/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc_solaris.cpp new file mode 100644 index 000000000..61f3df4ff --- /dev/null +++ b/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc_solaris.cpp @@ -0,0 +1,112 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Implement shared vtbl methods. */ + +#include "xptcprivate.h" +#include "xptiprivate.h" + +#if defined(sparc) || defined(__sparc__) + +extern "C" nsresult ATTRIBUTE_USED +PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args) +{ + + typedef struct { + uint32_t hi; + uint32_t lo; + } DU; // have to move 64 bit entities as 32 bit halves since + // stack slots are not guaranteed 16 byte aligned + +#define PARAM_BUFFER_COUNT 16 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = nullptr; + const nsXPTMethodInfo* info; + uint8_t paramCount; + uint8_t i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->mEntry->GetMethodInfo(uint16_t(methodIndex), &info); + NS_ASSERTION(info,"no interface info"); + + paramCount = info->GetParamCount(); + + // setup variant array pointer + if(paramCount > PARAM_BUFFER_COUNT) + dispatchParams = new nsXPTCMiniVariant[paramCount]; + else + dispatchParams = paramBuffer; + NS_ASSERTION(dispatchParams,"no place for params"); + + uint32_t* ap = args; + for(i = 0; i < paramCount; i++, ap++) + { + const nsXPTParamInfo& param = info->GetParam(i); + const nsXPTType& type = param.GetType(); + nsXPTCMiniVariant* dp = &dispatchParams[i]; + + if(param.IsOut() || !type.IsArithmetic()) + { + if (type == nsXPTType::T_JSVAL) + dp->val.p = *((void**) *ap); + else + dp->val.p = (void*) *ap; + continue; + } + // else + switch(type) + { + case nsXPTType::T_I8 : dp->val.i8 = *((int32_t*) ap); break; + case nsXPTType::T_I16 : dp->val.i16 = *((int32_t*) ap); break; + case nsXPTType::T_I32 : dp->val.i32 = *((int32_t*) ap); break; + case nsXPTType::T_DOUBLE : + case nsXPTType::T_U64 : + case nsXPTType::T_I64 : ((DU *)dp)->hi = ((DU *)ap)->hi; + ((DU *)dp)->lo = ((DU *)ap)->lo; + ap++; + break; + case nsXPTType::T_U8 : dp->val.u8 = *((uint32_t*)ap); break; + case nsXPTType::T_U16 : dp->val.u16 = *((uint32_t*)ap); break; + case nsXPTType::T_U32 : dp->val.u32 = *((uint32_t*)ap); break; + case nsXPTType::T_FLOAT : dp->val.f = *((float*) ap); break; + case nsXPTType::T_BOOL : dp->val.b = *((uint32_t*)ap); break; + case nsXPTType::T_CHAR : dp->val.c = *((uint32_t*)ap); break; + case nsXPTType::T_WCHAR : dp->val.wc = *((int32_t*) ap); break; + default: + NS_ERROR("bad type"); + break; + } + } + + result = self->mOuter->CallMethod((uint16_t)methodIndex, info, dispatchParams); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +extern "C" nsresult SharedStub(int, int*); + +#define STUB_ENTRY(n) \ +nsresult nsXPTCStubBase::Stub##n() \ +{ \ + int dummy; /* defeat tail-call optimization */ \ + return SharedStub(n, &dummy); \ +} + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ERROR("nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" + +#endif /* sparc || __sparc__ */ diff --git a/xpcom/reflect/xptcall/status.html b/xpcom/reflect/xptcall/status.html index deb4da92e..996159c82 100644 --- a/xpcom/reflect/xptcall/status.html +++ b/xpcom/reflect/xptcall/status.html @@ -241,6 +241,20 @@ a port. <TR> <TD bgcolor="green"><font color="white"><b>Done</b></font></TD> +<TD>SunOS x86</TD> +<TD> +<img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:aljones@lbl.gov">Arthur Jones <aljones@lbl.gov></a><BR> +<font color="red"><b>?</b></font> +<a href="mailto:ppokorny@mindspring.com">Philip Pokorny <ppokorny@mindspring.com></a><BR> +</TD> +<TD> +The word I hear is that this is working and done +</TD> +</TR> + +<TR> +<TD bgcolor="green"><font color="white"><b>Done</b></font></TD> <TD>Irix</TD> <TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> <a href="mailto:jasonh@m7.engr.sgi.com">Jason Heirtzler <jasonh@m7.engr.sgi.com></a><BR> diff --git a/xpcom/string/nsTSubstring.h b/xpcom/string/nsTSubstring.h index 53b4fb9a8..537889d5c 100644 --- a/xpcom/string/nsTSubstring.h +++ b/xpcom/string/nsTSubstring.h @@ -10,6 +10,14 @@ #include "mozilla/IntegerTypeTraits.h" #include "mozilla/Span.h" +// Solaris defines pid_t to be long on ILP32 and int on LP64. I checked in +// sys/types.h. AMD64 and SPARC64 builds don't need this fix at all, +// while all 32-bit builds do. + +#if defined(XP_SOLARIS) && !defined(__LP64__) +#include <unistd.h> +#endif + #ifndef MOZILLA_INTERNAL_API #error Cannot use internal string classes without MOZILLA_INTERNAL_API defined. Use the frozen header nsStringAPI.h instead. #endif @@ -587,6 +595,17 @@ public: const char* fmt = aRadix == 10 ? "%d" : aRadix == 8 ? "%o" : "%x"; AppendPrintf(fmt, aInteger); } +#if defined(XP_SOLARIS) && !defined(__LP64__) + void AppendInt(pid_t aInteger) + { + AppendPrintf("%lu", aInteger); + } + void AppendInt(pid_t aInteger, int aRadix) + { + const char* fmt = aRadix == 10 ? "%lu" : aRadix == 8 ? "%lo" : "%lx"; + AppendPrintf(fmt, aInteger); + } +#endif void AppendInt(uint32_t aInteger) { AppendPrintf("%u", aInteger); diff --git a/xpcom/threads/nsThreadPool.cpp b/xpcom/threads/nsThreadPool.cpp index 241fad39d..eb967870a 100644 --- a/xpcom/threads/nsThreadPool.cpp +++ b/xpcom/threads/nsThreadPool.cpp @@ -112,7 +112,9 @@ nsThreadPool::PutEvent(already_AddRefed<nsIRunnable> aEvent, uint32_t aFlags) bool killThread = false; { MutexAutoLock lock(mMutex); - if (mThreads.Count() < (int32_t)mThreadLimit) { + if (mShutdown) { + killThread = true; // we're in shutdown, kill the thread + } else if (mThreads.Count() < (int32_t)mThreadLimit) { mThreads.AppendObject(thread); } else { killThread = true; // okay, we don't need this thread anymore |