xpcom/reflect/xptcall/src/md/unix/xptcinvoke_x86_64_solaris.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  *
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 // Platform specific code to invoke XPCOM methods on native objects
     9 #include "xptcprivate.h"
    10 #include "alloca.h"
    12 // 6 integral parameters are passed in registers
    13 const uint32_t GPR_COUNT = 6;
    15 // 8 floating point parameters are passed in SSE registers
    16 const uint32_t FPR_COUNT = 8;
    18 // Remember that these 'words' are 64-bit long
    19 static inline void
    20 invoke_count_words(uint32_t paramCount, nsXPTCVariant * s,
    21                    uint32_t & nr_gpr, uint32_t & nr_fpr, uint32_t & nr_stack)
    22 {
    23     nr_gpr = 1; // skip one GP register for 'that'
    24     nr_fpr = 0;
    25     nr_stack = 0;
    27     /* Compute number of eightbytes of class MEMORY.  */
    28     for (uint32_t i = 0; i < paramCount; i++, s++) {
    29         if (!s->IsPtrData()
    30             && (s->type == nsXPTType::T_FLOAT || s->type == nsXPTType::T_DOUBLE)) {
    31             if (nr_fpr < FPR_COUNT)
    32                 nr_fpr++;
    33             else
    34                 nr_stack++;
    35         }
    36         else {
    37             if (nr_gpr < GPR_COUNT)
    38                 nr_gpr++;
    39             else
    40                 nr_stack++;
    41         }
    42     }
    43 }
    45 static void
    46 invoke_copy_to_stack(uint64_t * d, uint32_t paramCount, nsXPTCVariant * s,
    47                      uint64_t * gpregs, double * fpregs)
    48 {
    49     uint32_t nr_gpr = 1; // skip one GP register for 'that'
    50     uint32_t nr_fpr = 0;
    51     uint64_t value;
    53     for (uint32_t i = 0; i < paramCount; i++, s++) {
    54         if (s->IsPtrData())
    55             value = (uint64_t) s->ptr;
    56         else {
    57             switch (s->type) {
    58             case nsXPTType::T_FLOAT:                                break;
    59             case nsXPTType::T_DOUBLE:                               break;
    60             case nsXPTType::T_I8:     value = s->val.i8;            break;
    61             case nsXPTType::T_I16:    value = s->val.i16;           break;
    62             case nsXPTType::T_I32:    value = s->val.i32;           break;
    63             case nsXPTType::T_I64:    value = s->val.i64;           break;
    64             case nsXPTType::T_U8:     value = s->val.u8;            break;
    65             case nsXPTType::T_U16:    value = s->val.u16;           break;
    66             case nsXPTType::T_U32:    value = s->val.u32;           break;
    67             case nsXPTType::T_U64:    value = s->val.u64;           break;
    68             case nsXPTType::T_BOOL:   value = s->val.b;             break;
    69             case nsXPTType::T_CHAR:   value = s->val.c;             break;
    70             case nsXPTType::T_WCHAR:  value = s->val.wc;            break;
    71             default:                  value = (uint64_t) s->val.p;  break;
    72             }
    73         }
    75         if (!s->IsPtrData() && s->type == nsXPTType::T_DOUBLE) {
    76             if (nr_fpr < FPR_COUNT)
    77                 fpregs[nr_fpr++] = s->val.d;
    78             else {
    79                 *((double *)d) = s->val.d;
    80                 d++;
    81             }
    82         }
    83         else if (!s->IsPtrData() && s->type == nsXPTType::T_FLOAT) {
    84             if (nr_fpr < FPR_COUNT)
    85                 // The value in %xmm register is already prepared to
    86                 // be retrieved as a float. Therefore, we pass the
    87                 // value verbatim, as a double without conversion.
    88                 fpregs[nr_fpr++] = s->val.d;
    89             else {
    90                 *((float *)d) = s->val.f;
    91                 d++;
    92             }
    93         }
    94         else {
    95             if (nr_gpr < GPR_COUNT)
    96                 gpregs[nr_gpr++] = value;
    97             else
    98                 *d++ = value;
    99         }
   100     }
   101 }
   103 EXPORT_XPCOM_API(nsresult)
   104 NS_InvokeByIndex(nsISupports * that, uint32_t methodIndex,
   105                  uint32_t paramCount, nsXPTCVariant * params)
   106 {
   107     uint32_t nr_gpr, nr_fpr, nr_stack;
   108     invoke_count_words(paramCount, params, nr_gpr, nr_fpr, nr_stack);
   110     // Stack, if used, must be 16-bytes aligned
   111     if (nr_stack)
   112         nr_stack = (nr_stack + 1) & ~1;
   114     // Load parameters to stack, if necessary
   115     uint64_t *stack = (uint64_t *) __builtin_alloca(nr_stack * 8);
   116     uint64_t gpregs[GPR_COUNT];
   117     double fpregs[FPR_COUNT];
   118     invoke_copy_to_stack(stack, paramCount, params, gpregs, fpregs);
   120     switch (nr_fpr) {
   121       case 8: asm("movupd %0, %xmm7" : : "xmm7" (fpregs[7]));
   122       case 7: asm("movupd %0, %xmm6" : : "xmm6" (fpregs[6]));
   123       case 6: asm("movupd %0, %xmm5" : : "xmm5" (fpregs[5]));
   124       case 5: asm("movupd %0, %xmm4" : : "xmm4" (fpregs[4]));
   125       case 4: asm("movupd %0, %xmm3" : : "xmm3" (fpregs[3]));
   126       case 3: asm("movupd %0, %xmm2" : : "xmm2" (fpregs[2]));
   127       case 2: asm("movupd %0, %xmm1" : : "xmm1" (fpregs[1]));
   128       case 1: asm("movupd %0, %xmm0" : : "xmm0" (fpregs[0]));
   129       case 0:;
   130     }
   132     // Ensure that assignments to SSE registers won't be optimized away
   133     asm("" ::: "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7");
   135     // Get pointer to method
   136     uint64_t methodAddress = *((uint64_t *)that);
   137     methodAddress += 16 + 8 * methodIndex;
   138     methodAddress = *((uint64_t *)methodAddress);
   140     typedef uint32_t (*Method)(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t);
   141     uint32_t result = ((Method)methodAddress)((uint64_t)that, gpregs[1], gpregs[2], gpregs[3], gpregs[4], gpregs[5]);
   142     return result;
   143 }

mercurial