100 |
100 |
101 template <DecoratorSet decorators, typename T> |
101 template <DecoratorSet decorators, typename T> |
102 struct AccessFunctionTypes { |
102 struct AccessFunctionTypes { |
103 typedef T (*load_at_func_t)(oop base, ptrdiff_t offset); |
103 typedef T (*load_at_func_t)(oop base, ptrdiff_t offset); |
104 typedef void (*store_at_func_t)(oop base, ptrdiff_t offset, T value); |
104 typedef void (*store_at_func_t)(oop base, ptrdiff_t offset, T value); |
105 typedef T (*atomic_cmpxchg_at_func_t)(T new_value, oop base, ptrdiff_t offset, T compare_value); |
105 typedef T (*atomic_cmpxchg_at_func_t)(oop base, ptrdiff_t offset, T compare_value, T new_value); |
106 typedef T (*atomic_xchg_at_func_t)(oop base, ptrdiff_t offset, T new_value); |
106 typedef T (*atomic_xchg_at_func_t)(oop base, ptrdiff_t offset, T new_value); |
107 |
107 |
108 typedef T (*load_func_t)(void* addr); |
108 typedef T (*load_func_t)(void* addr); |
109 typedef void (*store_func_t)(void* addr, T value); |
109 typedef void (*store_func_t)(void* addr, T value); |
110 typedef T (*atomic_cmpxchg_func_t)(T new_value, void* addr, T compare_value); |
110 typedef T (*atomic_cmpxchg_func_t)(void* addr, T compare_value, T new_value); |
111 typedef T (*atomic_xchg_func_t)(void* addr, T new_value); |
111 typedef T (*atomic_xchg_func_t)(void* addr, T new_value); |
112 |
112 |
113 typedef bool (*arraycopy_func_t)(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw, |
113 typedef bool (*arraycopy_func_t)(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw, |
114 arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw, |
114 arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw, |
115 size_t length); |
115 size_t length); |
291 } |
291 } |
292 |
292 |
293 template <DecoratorSet ds, typename T> |
293 template <DecoratorSet ds, typename T> |
294 static typename EnableIf< |
294 static typename EnableIf< |
295 HasDecorator<ds, MO_SEQ_CST>::value, T>::type |
295 HasDecorator<ds, MO_SEQ_CST>::value, T>::type |
296 atomic_cmpxchg_internal(T new_value, void* addr, T compare_value); |
296 atomic_cmpxchg_internal(void* addr, T compare_value, T new_value); |
297 |
297 |
298 template <DecoratorSet ds, typename T> |
298 template <DecoratorSet ds, typename T> |
299 static typename EnableIf< |
299 static typename EnableIf< |
300 HasDecorator<ds, MO_RELAXED>::value, T>::type |
300 HasDecorator<ds, MO_RELAXED>::value, T>::type |
301 atomic_cmpxchg_internal(T new_value, void* addr, T compare_value); |
301 atomic_cmpxchg_internal(void* addr, T compare_value, T new_value); |
302 |
302 |
303 template <DecoratorSet ds, typename T> |
303 template <DecoratorSet ds, typename T> |
304 static typename EnableIf< |
304 static typename EnableIf< |
305 HasDecorator<ds, MO_SEQ_CST>::value, T>::type |
305 HasDecorator<ds, MO_SEQ_CST>::value, T>::type |
306 atomic_xchg_internal(void* addr, T new_value); |
306 atomic_xchg_internal(void* addr, T new_value); |
310 // a slower path using a mutex to perform the operation. |
310 // a slower path using a mutex to perform the operation. |
311 |
311 |
312 template <DecoratorSet ds, typename T> |
312 template <DecoratorSet ds, typename T> |
313 static inline typename EnableIf< |
313 static inline typename EnableIf< |
314 !AccessInternal::PossiblyLockedAccess<T>::value, T>::type |
314 !AccessInternal::PossiblyLockedAccess<T>::value, T>::type |
315 atomic_cmpxchg_maybe_locked(T new_value, void* addr, T compare_value) { |
315 atomic_cmpxchg_maybe_locked(void* addr, T compare_value, T new_value) { |
316 return atomic_cmpxchg_internal<ds>(new_value, addr, compare_value); |
316 return atomic_cmpxchg_internal<ds>(addr, compare_value, new_value); |
317 } |
317 } |
318 |
318 |
319 template <DecoratorSet ds, typename T> |
319 template <DecoratorSet ds, typename T> |
320 static typename EnableIf< |
320 static typename EnableIf< |
321 AccessInternal::PossiblyLockedAccess<T>::value, T>::type |
321 AccessInternal::PossiblyLockedAccess<T>::value, T>::type |
322 atomic_cmpxchg_maybe_locked(T new_value, void* addr, T compare_value); |
322 atomic_cmpxchg_maybe_locked(void* addr, T compare_value, T new_value); |
323 |
323 |
324 template <DecoratorSet ds, typename T> |
324 template <DecoratorSet ds, typename T> |
325 static inline typename EnableIf< |
325 static inline typename EnableIf< |
326 !AccessInternal::PossiblyLockedAccess<T>::value, T>::type |
326 !AccessInternal::PossiblyLockedAccess<T>::value, T>::type |
327 atomic_xchg_maybe_locked(void* addr, T new_value) { |
327 atomic_xchg_maybe_locked(void* addr, T new_value) { |
368 static T oop_load(void* addr); |
368 static T oop_load(void* addr); |
369 template <typename T> |
369 template <typename T> |
370 static T oop_load_at(oop base, ptrdiff_t offset); |
370 static T oop_load_at(oop base, ptrdiff_t offset); |
371 |
371 |
372 template <typename T> |
372 template <typename T> |
373 static T oop_atomic_cmpxchg(T new_value, void* addr, T compare_value); |
373 static T oop_atomic_cmpxchg(void* addr, T compare_value, T new_value); |
374 template <typename T> |
374 template <typename T> |
375 static T oop_atomic_cmpxchg_at(T new_value, oop base, ptrdiff_t offset, T compare_value); |
375 static T oop_atomic_cmpxchg_at(oop base, ptrdiff_t offset, T compare_value, T new_value); |
376 |
376 |
377 template <typename T> |
377 template <typename T> |
378 static T oop_atomic_xchg(void* addr, T new_value); |
378 static T oop_atomic_xchg(void* addr, T new_value); |
379 template <typename T> |
379 template <typename T> |
380 static T oop_atomic_xchg_at(oop base, ptrdiff_t offset, T new_value); |
380 static T oop_atomic_xchg_at(oop base, ptrdiff_t offset, T new_value); |
513 template <DecoratorSet decorators, typename T> |
513 template <DecoratorSet decorators, typename T> |
514 struct RuntimeDispatch<decorators, T, BARRIER_ATOMIC_CMPXCHG>: AllStatic { |
514 struct RuntimeDispatch<decorators, T, BARRIER_ATOMIC_CMPXCHG>: AllStatic { |
515 typedef typename AccessFunction<decorators, T, BARRIER_ATOMIC_CMPXCHG>::type func_t; |
515 typedef typename AccessFunction<decorators, T, BARRIER_ATOMIC_CMPXCHG>::type func_t; |
516 static func_t _atomic_cmpxchg_func; |
516 static func_t _atomic_cmpxchg_func; |
517 |
517 |
518 static T atomic_cmpxchg_init(T new_value, void* addr, T compare_value); |
518 static T atomic_cmpxchg_init(void* addr, T compare_value, T new_value); |
519 |
519 |
520 static inline T atomic_cmpxchg(T new_value, void* addr, T compare_value) { |
520 static inline T atomic_cmpxchg(void* addr, T compare_value, T new_value) { |
521 return _atomic_cmpxchg_func(new_value, addr, compare_value); |
521 return _atomic_cmpxchg_func(addr, compare_value, new_value); |
522 } |
522 } |
523 }; |
523 }; |
524 |
524 |
525 template <DecoratorSet decorators, typename T> |
525 template <DecoratorSet decorators, typename T> |
526 struct RuntimeDispatch<decorators, T, BARRIER_ATOMIC_CMPXCHG_AT>: AllStatic { |
526 struct RuntimeDispatch<decorators, T, BARRIER_ATOMIC_CMPXCHG_AT>: AllStatic { |
527 typedef typename AccessFunction<decorators, T, BARRIER_ATOMIC_CMPXCHG_AT>::type func_t; |
527 typedef typename AccessFunction<decorators, T, BARRIER_ATOMIC_CMPXCHG_AT>::type func_t; |
528 static func_t _atomic_cmpxchg_at_func; |
528 static func_t _atomic_cmpxchg_at_func; |
529 |
529 |
530 static T atomic_cmpxchg_at_init(T new_value, oop base, ptrdiff_t offset, T compare_value); |
530 static T atomic_cmpxchg_at_init(oop base, ptrdiff_t offset, T compare_value, T new_value); |
531 |
531 |
532 static inline T atomic_cmpxchg_at(T new_value, oop base, ptrdiff_t offset, T compare_value) { |
532 static inline T atomic_cmpxchg_at(oop base, ptrdiff_t offset, T compare_value, T new_value) { |
533 return _atomic_cmpxchg_at_func(new_value, base, offset, compare_value); |
533 return _atomic_cmpxchg_at_func(base, offset, compare_value, new_value); |
534 } |
534 } |
535 }; |
535 }; |
536 |
536 |
537 template <DecoratorSet decorators, typename T> |
537 template <DecoratorSet decorators, typename T> |
538 struct RuntimeDispatch<decorators, T, BARRIER_ATOMIC_XCHG>: AllStatic { |
538 struct RuntimeDispatch<decorators, T, BARRIER_ATOMIC_XCHG>: AllStatic { |
780 } |
780 } |
781 |
781 |
782 template <DecoratorSet decorators, typename T> |
782 template <DecoratorSet decorators, typename T> |
783 inline static typename EnableIf< |
783 inline static typename EnableIf< |
784 HasDecorator<decorators, AS_RAW>::value && CanHardwireRaw<decorators>::value, T>::type |
784 HasDecorator<decorators, AS_RAW>::value && CanHardwireRaw<decorators>::value, T>::type |
785 atomic_cmpxchg(T new_value, void* addr, T compare_value) { |
785 atomic_cmpxchg(void* addr, T compare_value, T new_value) { |
786 typedef RawAccessBarrier<decorators & RAW_DECORATOR_MASK> Raw; |
786 typedef RawAccessBarrier<decorators & RAW_DECORATOR_MASK> Raw; |
787 if (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value) { |
787 if (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value) { |
788 return Raw::oop_atomic_cmpxchg(new_value, addr, compare_value); |
788 return Raw::oop_atomic_cmpxchg(addr, compare_value, new_value); |
789 } else { |
789 } else { |
790 return Raw::atomic_cmpxchg(new_value, addr, compare_value); |
790 return Raw::atomic_cmpxchg(addr, compare_value, new_value); |
791 } |
791 } |
792 } |
792 } |
793 |
793 |
794 template <DecoratorSet decorators, typename T> |
794 template <DecoratorSet decorators, typename T> |
795 inline static typename EnableIf< |
795 inline static typename EnableIf< |
796 HasDecorator<decorators, AS_RAW>::value && !CanHardwireRaw<decorators>::value, T>::type |
796 HasDecorator<decorators, AS_RAW>::value && !CanHardwireRaw<decorators>::value, T>::type |
797 atomic_cmpxchg(T new_value, void* addr, T compare_value) { |
797 atomic_cmpxchg(void* addr, T compare_value, T new_value) { |
798 if (UseCompressedOops) { |
798 if (UseCompressedOops) { |
799 const DecoratorSet expanded_decorators = decorators | convert_compressed_oops; |
799 const DecoratorSet expanded_decorators = decorators | convert_compressed_oops; |
800 return PreRuntimeDispatch::atomic_cmpxchg<expanded_decorators>(new_value, addr, compare_value); |
800 return PreRuntimeDispatch::atomic_cmpxchg<expanded_decorators>(addr, compare_value, new_value); |
801 } else { |
801 } else { |
802 const DecoratorSet expanded_decorators = decorators & ~convert_compressed_oops; |
802 const DecoratorSet expanded_decorators = decorators & ~convert_compressed_oops; |
803 return PreRuntimeDispatch::atomic_cmpxchg<expanded_decorators>(new_value, addr, compare_value); |
803 return PreRuntimeDispatch::atomic_cmpxchg<expanded_decorators>(addr, compare_value, new_value); |
804 } |
804 } |
805 } |
805 } |
806 |
806 |
807 template <DecoratorSet decorators, typename T> |
807 template <DecoratorSet decorators, typename T> |
808 inline static typename EnableIf< |
808 inline static typename EnableIf< |
809 !HasDecorator<decorators, AS_RAW>::value, T>::type |
809 !HasDecorator<decorators, AS_RAW>::value, T>::type |
810 atomic_cmpxchg(T new_value, void* addr, T compare_value) { |
810 atomic_cmpxchg(void* addr, T compare_value, T new_value) { |
811 if (is_hardwired_primitive<decorators>()) { |
811 if (is_hardwired_primitive<decorators>()) { |
812 const DecoratorSet expanded_decorators = decorators | AS_RAW; |
812 const DecoratorSet expanded_decorators = decorators | AS_RAW; |
813 return PreRuntimeDispatch::atomic_cmpxchg<expanded_decorators>(new_value, addr, compare_value); |
813 return PreRuntimeDispatch::atomic_cmpxchg<expanded_decorators>(addr, compare_value, new_value); |
814 } else { |
814 } else { |
815 return RuntimeDispatch<decorators, T, BARRIER_ATOMIC_CMPXCHG>::atomic_cmpxchg(new_value, addr, compare_value); |
815 return RuntimeDispatch<decorators, T, BARRIER_ATOMIC_CMPXCHG>::atomic_cmpxchg(addr, compare_value, new_value); |
816 } |
816 } |
817 } |
817 } |
818 |
818 |
819 template <DecoratorSet decorators, typename T> |
819 template <DecoratorSet decorators, typename T> |
820 inline static typename EnableIf< |
820 inline static typename EnableIf< |
821 HasDecorator<decorators, AS_RAW>::value, T>::type |
821 HasDecorator<decorators, AS_RAW>::value, T>::type |
822 atomic_cmpxchg_at(T new_value, oop base, ptrdiff_t offset, T compare_value) { |
822 atomic_cmpxchg_at(oop base, ptrdiff_t offset, T compare_value, T new_value) { |
823 return atomic_cmpxchg<decorators>(new_value, field_addr(base, offset), compare_value); |
823 return atomic_cmpxchg<decorators>(field_addr(base, offset), compare_value, new_value); |
824 } |
824 } |
825 |
825 |
826 template <DecoratorSet decorators, typename T> |
826 template <DecoratorSet decorators, typename T> |
827 inline static typename EnableIf< |
827 inline static typename EnableIf< |
828 !HasDecorator<decorators, AS_RAW>::value, T>::type |
828 !HasDecorator<decorators, AS_RAW>::value, T>::type |
829 atomic_cmpxchg_at(T new_value, oop base, ptrdiff_t offset, T compare_value) { |
829 atomic_cmpxchg_at(oop base, ptrdiff_t offset, T compare_value, T new_value) { |
830 if (is_hardwired_primitive<decorators>()) { |
830 if (is_hardwired_primitive<decorators>()) { |
831 const DecoratorSet expanded_decorators = decorators | AS_RAW; |
831 const DecoratorSet expanded_decorators = decorators | AS_RAW; |
832 return PreRuntimeDispatch::atomic_cmpxchg_at<expanded_decorators>(new_value, base, offset, compare_value); |
832 return PreRuntimeDispatch::atomic_cmpxchg_at<expanded_decorators>(base, offset, compare_value, new_value); |
833 } else { |
833 } else { |
834 return RuntimeDispatch<decorators, T, BARRIER_ATOMIC_CMPXCHG_AT>::atomic_cmpxchg_at(new_value, base, offset, compare_value); |
834 return RuntimeDispatch<decorators, T, BARRIER_ATOMIC_CMPXCHG_AT>::atomic_cmpxchg_at(base, offset, compare_value, new_value); |
835 } |
835 } |
836 } |
836 } |
837 |
837 |
838 template <DecoratorSet decorators, typename T> |
838 template <DecoratorSet decorators, typename T> |
839 inline static typename EnableIf< |
839 inline static typename EnableIf< |
1016 const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP; |
1016 const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP; |
1017 PreRuntimeDispatch::store<expanded_decorators>(addr, value); |
1017 PreRuntimeDispatch::store<expanded_decorators>(addr, value); |
1018 } |
1018 } |
1019 |
1019 |
1020 template <DecoratorSet decorators, typename T> |
1020 template <DecoratorSet decorators, typename T> |
1021 inline T atomic_cmpxchg_reduce_types(T new_value, T* addr, T compare_value) { |
1021 inline T atomic_cmpxchg_reduce_types(T* addr, T compare_value, T new_value) { |
1022 return PreRuntimeDispatch::atomic_cmpxchg<decorators>(new_value, addr, compare_value); |
1022 return PreRuntimeDispatch::atomic_cmpxchg<decorators>(addr, compare_value, new_value); |
1023 } |
1023 } |
1024 |
1024 |
1025 template <DecoratorSet decorators> |
1025 template <DecoratorSet decorators> |
1026 inline oop atomic_cmpxchg_reduce_types(oop new_value, narrowOop* addr, oop compare_value) { |
1026 inline oop atomic_cmpxchg_reduce_types(narrowOop* addr, oop compare_value, oop new_value) { |
1027 const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP | |
1027 const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP | |
1028 INTERNAL_RT_USE_COMPRESSED_OOPS; |
1028 INTERNAL_RT_USE_COMPRESSED_OOPS; |
1029 return PreRuntimeDispatch::atomic_cmpxchg<expanded_decorators>(new_value, addr, compare_value); |
1029 return PreRuntimeDispatch::atomic_cmpxchg<expanded_decorators>(addr, compare_value, new_value); |
1030 } |
1030 } |
1031 |
1031 |
1032 template <DecoratorSet decorators> |
1032 template <DecoratorSet decorators> |
1033 inline narrowOop atomic_cmpxchg_reduce_types(narrowOop new_value, narrowOop* addr, narrowOop compare_value) { |
1033 inline narrowOop atomic_cmpxchg_reduce_types(narrowOop* addr, narrowOop compare_value, narrowOop new_value) { |
1034 const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP | |
1034 const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP | |
1035 INTERNAL_RT_USE_COMPRESSED_OOPS; |
1035 INTERNAL_RT_USE_COMPRESSED_OOPS; |
1036 return PreRuntimeDispatch::atomic_cmpxchg<expanded_decorators>(new_value, addr, compare_value); |
1036 return PreRuntimeDispatch::atomic_cmpxchg<expanded_decorators>(addr, compare_value, new_value); |
1037 } |
1037 } |
1038 |
1038 |
1039 template <DecoratorSet decorators> |
1039 template <DecoratorSet decorators> |
1040 inline oop atomic_cmpxchg_reduce_types(oop new_value, |
1040 inline oop atomic_cmpxchg_reduce_types(HeapWord* addr, |
1041 HeapWord* addr, |
1041 oop compare_value, |
1042 oop compare_value) { |
1042 oop new_value) { |
1043 const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP; |
1043 const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP; |
1044 return PreRuntimeDispatch::atomic_cmpxchg<expanded_decorators>(new_value, addr, compare_value); |
1044 return PreRuntimeDispatch::atomic_cmpxchg<expanded_decorators>(addr, compare_value, new_value); |
1045 } |
1045 } |
1046 |
1046 |
1047 template <DecoratorSet decorators, typename T> |
1047 template <DecoratorSet decorators, typename T> |
1048 inline T atomic_xchg_reduce_types(T* addr, T new_value) { |
1048 inline T atomic_xchg_reduce_types(T* addr, T new_value) { |
1049 const DecoratorSet expanded_decorators = decorators; |
1049 const DecoratorSet expanded_decorators = decorators; |
1189 INTERNAL_CONVERT_COMPRESSED_OOP : DECORATORS_NONE)>::value; |
1189 INTERNAL_CONVERT_COMPRESSED_OOP : DECORATORS_NONE)>::value; |
1190 return PreRuntimeDispatch::load_at<expanded_decorators, DecayedT>(base, offset); |
1190 return PreRuntimeDispatch::load_at<expanded_decorators, DecayedT>(base, offset); |
1191 } |
1191 } |
1192 |
1192 |
1193 template <DecoratorSet decorators, typename P, typename T> |
1193 template <DecoratorSet decorators, typename P, typename T> |
1194 inline T atomic_cmpxchg(T new_value, P* addr, T compare_value) { |
1194 inline T atomic_cmpxchg(P* addr, T compare_value, T new_value) { |
1195 verify_types<decorators, T>(); |
1195 verify_types<decorators, T>(); |
1196 typedef typename Decay<P>::type DecayedP; |
1196 typedef typename Decay<P>::type DecayedP; |
1197 typedef typename Decay<T>::type DecayedT; |
1197 typedef typename Decay<T>::type DecayedT; |
1198 DecayedT new_decayed_value = new_value; |
1198 DecayedT new_decayed_value = new_value; |
1199 DecayedT compare_decayed_value = compare_value; |
1199 DecayedT compare_decayed_value = compare_value; |
1200 const DecoratorSet expanded_decorators = DecoratorFixup< |
1200 const DecoratorSet expanded_decorators = DecoratorFixup< |
1201 (!HasDecorator<decorators, MO_DECORATOR_MASK>::value) ? |
1201 (!HasDecorator<decorators, MO_DECORATOR_MASK>::value) ? |
1202 (MO_SEQ_CST | decorators) : decorators>::value; |
1202 (MO_SEQ_CST | decorators) : decorators>::value; |
1203 return atomic_cmpxchg_reduce_types<expanded_decorators>(new_decayed_value, |
1203 return atomic_cmpxchg_reduce_types<expanded_decorators>(const_cast<DecayedP*>(addr), |
1204 const_cast<DecayedP*>(addr), |
1204 compare_decayed_value, |
1205 compare_decayed_value); |
1205 new_decayed_value); |
1206 } |
1206 } |
1207 |
1207 |
1208 template <DecoratorSet decorators, typename T> |
1208 template <DecoratorSet decorators, typename T> |
1209 inline T atomic_cmpxchg_at(T new_value, oop base, ptrdiff_t offset, T compare_value) { |
1209 inline T atomic_cmpxchg_at(oop base, ptrdiff_t offset, T compare_value, T new_value) { |
1210 verify_types<decorators, T>(); |
1210 verify_types<decorators, T>(); |
1211 typedef typename Decay<T>::type DecayedT; |
1211 typedef typename Decay<T>::type DecayedT; |
1212 DecayedT new_decayed_value = new_value; |
1212 DecayedT new_decayed_value = new_value; |
1213 DecayedT compare_decayed_value = compare_value; |
1213 DecayedT compare_decayed_value = compare_value; |
1214 // Determine default memory ordering |
1214 // Determine default memory ordering |
1217 (MO_SEQ_CST | decorators) : decorators>::value; |
1217 (MO_SEQ_CST | decorators) : decorators>::value; |
1218 // Potentially remember that we need compressed oop awareness |
1218 // Potentially remember that we need compressed oop awareness |
1219 const DecoratorSet final_decorators = expanded_decorators | |
1219 const DecoratorSet final_decorators = expanded_decorators | |
1220 (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value ? |
1220 (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value ? |
1221 INTERNAL_CONVERT_COMPRESSED_OOP : DECORATORS_NONE); |
1221 INTERNAL_CONVERT_COMPRESSED_OOP : DECORATORS_NONE); |
1222 return PreRuntimeDispatch::atomic_cmpxchg_at<final_decorators>(new_decayed_value, base, |
1222 return PreRuntimeDispatch::atomic_cmpxchg_at<final_decorators>(base, offset, compare_decayed_value, |
1223 offset, compare_decayed_value); |
1223 new_decayed_value); |
1224 } |
1224 } |
1225 |
1225 |
1226 template <DecoratorSet decorators, typename P, typename T> |
1226 template <DecoratorSet decorators, typename P, typename T> |
1227 inline T atomic_xchg(P* addr, T new_value) { |
1227 inline T atomic_xchg(P* addr, T new_value) { |
1228 verify_types<decorators, T>(); |
1228 verify_types<decorators, T>(); |