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.

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

mercurial