AtomicOp.h (3454B)
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 #ifndef jit_AtomicOp_h 8 #define jit_AtomicOp_h 9 10 #include <stdint.h> 11 12 namespace js { 13 namespace jit { 14 15 // Types of atomic operation, shared by MIR and LIR. 16 17 enum class AtomicOp { 18 Add, 19 Sub, 20 And, 21 Or, 22 Xor, 23 }; 24 25 // Memory barrier type, shared by MIR and LIR. 26 class MemoryBarrier { 27 enum MemoryBarrierBits : uint8_t { 28 MembarLoadLoad = 1, 29 MembarLoadStore = 2, 30 MembarStoreStore = 4, 31 MembarStoreLoad = 8, 32 33 // MembarSynchronizing is here because some platforms can make the 34 // distinction (DSB vs DMB on ARM, SYNC vs parameterized SYNC on MIPS) 35 // but there's been no reason to use it yet. 36 MembarSynchronizing = 16, 37 38 // For validity testing 39 MembarNobits = 0, 40 MembarAllbits = 31, 41 }; 42 43 MemoryBarrierBits bits_; 44 45 template <typename... MembarBits> 46 constexpr explicit MemoryBarrier(MembarBits... bits) 47 : bits_(static_cast<MemoryBarrierBits>((bits | ...))) {} 48 49 public: 50 // Accessors for currently used memory barrier types. 51 52 constexpr bool isNone() const { return bits_ == MembarNobits; } 53 54 constexpr bool isStoreStore() const { return bits_ == MembarStoreStore; } 55 56 constexpr bool isSyncStoreStore() const { 57 return bits_ == static_cast<MemoryBarrierBits>(MembarStoreStore | 58 MembarSynchronizing); 59 } 60 61 constexpr bool hasSync() const { return bits_ & MembarSynchronizing; } 62 63 constexpr bool hasStoreLoad() const { return bits_ & MembarStoreLoad; } 64 65 // No memory barrier. 66 static constexpr MemoryBarrier None() { return MemoryBarrier{MembarNobits}; } 67 68 // Full memory barrier. 69 static constexpr MemoryBarrier Full() { 70 return MemoryBarrier{MembarLoadLoad, MembarLoadStore, MembarStoreLoad, 71 MembarStoreStore}; 72 } 73 74 // Standard sets of barriers for atomic loads and stores. 75 // See http://gee.cs.oswego.edu/dl/jmm/cookbook.html for more. 76 static constexpr MemoryBarrier BeforeLoad() { 77 return MemoryBarrier{MembarNobits}; 78 } 79 static constexpr MemoryBarrier AfterLoad() { 80 return MemoryBarrier{MembarLoadLoad, MembarLoadStore}; 81 } 82 static constexpr MemoryBarrier BeforeStore() { 83 return MemoryBarrier{MembarStoreStore}; 84 } 85 static constexpr MemoryBarrier AfterStore() { 86 return MemoryBarrier{MembarStoreLoad}; 87 } 88 }; 89 90 struct Synchronization { 91 const MemoryBarrier barrierBefore; 92 const MemoryBarrier barrierAfter; 93 94 constexpr Synchronization(MemoryBarrier before, MemoryBarrier after) 95 : barrierBefore(before), barrierAfter(after) {} 96 97 static constexpr Synchronization None() { 98 return {MemoryBarrier::None(), MemoryBarrier::None()}; 99 } 100 101 static constexpr Synchronization Full() { 102 return {MemoryBarrier::Full(), MemoryBarrier::Full()}; 103 } 104 105 static constexpr Synchronization Load() { 106 return {MemoryBarrier::BeforeLoad(), MemoryBarrier::AfterLoad()}; 107 } 108 109 static constexpr Synchronization Store() { 110 return {MemoryBarrier::BeforeStore(), MemoryBarrier::AfterStore()}; 111 } 112 113 constexpr bool isNone() const { 114 return barrierBefore.isNone() && barrierAfter.isNone(); 115 } 116 }; 117 118 } // namespace jit 119 } // namespace js 120 121 #endif /* jit_AtomicOp_h */