tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

AtomicOperations-mips-shared.h (6247B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      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/. */
      6 
      7 /* For documentation, see jit/AtomicOperations.h */
      8 
      9 #ifndef jit_mips_shared_AtomicOperations_mips_shared_h
     10 #define jit_mips_shared_AtomicOperations_mips_shared_h
     11 
     12 #include "mozilla/Assertions.h"
     13 
     14 #include "builtin/AtomicsObject.h"
     15 #include "vm/Uint8Clamped.h"
     16 
     17 #if !defined(__clang__) && !defined(__GNUC__)
     18 #  error "This file only for gcc-compatible compilers"
     19 #endif
     20 
     21 inline bool js::jit::AtomicOperations::hasAtomic8() { return true; }
     22 
     23 inline bool js::jit::AtomicOperations::isLockfree8() {
     24  MOZ_ASSERT(__atomic_always_lock_free(sizeof(int8_t), 0));
     25  MOZ_ASSERT(__atomic_always_lock_free(sizeof(int16_t), 0));
     26  MOZ_ASSERT(__atomic_always_lock_free(sizeof(int32_t), 0));
     27  MOZ_ASSERT(__atomic_always_lock_free(sizeof(int64_t), 0));
     28  return true;
     29 }
     30 
     31 inline void js::jit::AtomicOperations::fenceSeqCst() {
     32  __atomic_thread_fence(__ATOMIC_SEQ_CST);
     33 }
     34 
     35 namespace js {
     36 namespace jit {
     37 
     38 inline void AtomicPause() { asm volatile("sync" ::: "memory"); }
     39 
     40 }  // namespace jit
     41 }  // namespace js
     42 
     43 inline void js::jit::AtomicOperations::pause() { AtomicPause(); }
     44 
     45 template <typename T>
     46 inline T js::jit::AtomicOperations::loadSeqCst(T* addr) {
     47  static_assert(sizeof(T) <= sizeof(void*),
     48                "atomics supported up to pointer size only");
     49  T v;
     50  __atomic_load(addr, &v, __ATOMIC_SEQ_CST);
     51  return v;
     52 }
     53 
     54 template <typename T>
     55 inline void js::jit::AtomicOperations::storeSeqCst(T* addr, T val) {
     56  static_assert(sizeof(T) <= sizeof(void*),
     57                "atomics supported up to pointer size only");
     58  __atomic_store(addr, &val, __ATOMIC_SEQ_CST);
     59 }
     60 
     61 template <typename T>
     62 inline T js::jit::AtomicOperations::compareExchangeSeqCst(T* addr, T oldval,
     63                                                          T newval) {
     64  static_assert(sizeof(T) <= sizeof(void*),
     65                "atomics supported up to pointer size only");
     66  __atomic_compare_exchange(addr, &oldval, &newval, false, __ATOMIC_SEQ_CST,
     67                            __ATOMIC_SEQ_CST);
     68  return oldval;
     69 }
     70 
     71 template <typename T>
     72 inline T js::jit::AtomicOperations::fetchAddSeqCst(T* addr, T val) {
     73  static_assert(sizeof(T) <= sizeof(void*),
     74                "atomics supported up to pointer size only");
     75  return __atomic_fetch_add(addr, val, __ATOMIC_SEQ_CST);
     76 }
     77 
     78 template <typename T>
     79 inline T js::jit::AtomicOperations::fetchSubSeqCst(T* addr, T val) {
     80  static_assert(sizeof(T) <= sizeof(void*),
     81                "atomics supported up to pointer size only");
     82  return __atomic_fetch_sub(addr, val, __ATOMIC_SEQ_CST);
     83 }
     84 
     85 template <typename T>
     86 inline T js::jit::AtomicOperations::fetchAndSeqCst(T* addr, T val) {
     87  static_assert(sizeof(T) <= sizeof(void*),
     88                "atomics supported up to pointer size only");
     89  return __atomic_fetch_and(addr, val, __ATOMIC_SEQ_CST);
     90 }
     91 
     92 template <typename T>
     93 inline T js::jit::AtomicOperations::fetchOrSeqCst(T* addr, T val) {
     94  static_assert(sizeof(T) <= sizeof(void*),
     95                "atomics supported up to pointer size only");
     96  return __atomic_fetch_or(addr, val, __ATOMIC_SEQ_CST);
     97 }
     98 
     99 template <typename T>
    100 inline T js::jit::AtomicOperations::fetchXorSeqCst(T* addr, T val) {
    101  static_assert(sizeof(T) <= sizeof(void*),
    102                "atomics supported up to pointer size only");
    103  return __atomic_fetch_xor(addr, val, __ATOMIC_SEQ_CST);
    104 }
    105 
    106 template <typename T>
    107 inline T js::jit::AtomicOperations::loadSafeWhenRacy(T* addr) {
    108  static_assert(sizeof(T) <= sizeof(void*),
    109                "atomics supported up to pointer size only");
    110  T v;
    111  __atomic_load(addr, &v, __ATOMIC_RELAXED);
    112  return v;
    113 }
    114 
    115 namespace js {
    116 namespace jit {
    117 
    118 template <>
    119 inline uint8_clamped js::jit::AtomicOperations::loadSafeWhenRacy(
    120    uint8_clamped* addr) {
    121  uint8_t v;
    122  __atomic_load((uint8_t*)addr, &v, __ATOMIC_RELAXED);
    123  return uint8_clamped(v);
    124 }
    125 
    126 template <>
    127 inline float js::jit::AtomicOperations::loadSafeWhenRacy(float* addr) {
    128  return *addr;
    129 }
    130 
    131 template <>
    132 inline double js::jit::AtomicOperations::loadSafeWhenRacy(double* addr) {
    133  return *addr;
    134 }
    135 
    136 }  // namespace jit
    137 }  // namespace js
    138 
    139 template <typename T>
    140 inline void js::jit::AtomicOperations::storeSafeWhenRacy(T* addr, T val) {
    141  static_assert(sizeof(T) <= sizeof(void*),
    142                "atomics supported up to pointer size only");
    143  __atomic_store(addr, &val, __ATOMIC_RELAXED);
    144 }
    145 
    146 namespace js {
    147 namespace jit {
    148 
    149 template <>
    150 inline void js::jit::AtomicOperations::storeSafeWhenRacy(uint8_clamped* addr,
    151                                                         uint8_clamped val) {
    152  __atomic_store((uint8_t*)addr, (uint8_t*)&val, __ATOMIC_RELAXED);
    153 }
    154 
    155 template <>
    156 inline void js::jit::AtomicOperations::storeSafeWhenRacy(float* addr,
    157                                                         float val) {
    158  *addr = val;
    159 }
    160 
    161 template <>
    162 inline void js::jit::AtomicOperations::storeSafeWhenRacy(double* addr,
    163                                                         double val) {
    164  *addr = val;
    165 }
    166 
    167 }  // namespace jit
    168 }  // namespace js
    169 
    170 inline void js::jit::AtomicOperations::memcpySafeWhenRacy(void* dest,
    171                                                          const void* src,
    172                                                          size_t nbytes) {
    173  MOZ_ASSERT(!((char*)dest <= (char*)src && (char*)src < (char*)dest + nbytes));
    174  MOZ_ASSERT(!((char*)src <= (char*)dest && (char*)dest < (char*)src + nbytes));
    175  ::memcpy(dest, src, nbytes);
    176 }
    177 
    178 inline void js::jit::AtomicOperations::memmoveSafeWhenRacy(void* dest,
    179                                                           const void* src,
    180                                                           size_t nbytes) {
    181  ::memmove(dest, src, nbytes);
    182 }
    183 
    184 template <typename T>
    185 inline T js::jit::AtomicOperations::exchangeSeqCst(T* addr, T val) {
    186  static_assert(sizeof(T) <= sizeof(void*),
    187                "atomics supported up to pointer size only");
    188  T v;
    189  __atomic_exchange(addr, &val, &v, __ATOMIC_SEQ_CST);
    190  return v;
    191 }
    192 
    193 #endif  // jit_mips_shared_AtomicOperations_mips_shared_h