< prev index next >

src/share/vm/runtime/atomic.hpp

Print this page
rev 13452 : imported patch Atomic_cmpxchg
rev 13453 : imported patch Atomic_add
rev 13454 : [mq]: Atomic_add_v2

@@ -217,10 +217,11 @@
   // scaling of the addend, as that has already been done by the
   // caller.
 public: // Temporary, can't be private: C++03 11.4/2. Fixed by C++11.
   template<typename Derived> struct FetchAndAdd;
   template<typename Derived> struct AddAndFetch;
+  struct AddShortUsingInt;
 private:
 
   // Support for platforms that implement some variants of add using a
   // (typically out of line) non-template helper function.  The
   // generic arguments passed to PlatformAdd need to be translated to

@@ -310,10 +311,24 @@
 struct Atomic::AddAndFetch VALUE_OBJ_CLASS_SPEC {
   template<typename I, typename D>
   D operator()(I add_value, D volatile* dest) const;
 };
 
+// Most platforms do not support atomic add on a 2-byte value. However,
+// if the value occupies the most significant 16 bits of an aligned 32-bit
+// word, then we can do this with an atomic add of (add_value << 16)
+// to the 32-bit word.
+//
+// The least significant parts of this 32-bit word will never be affected, even
+// in case of overflow/underflow.
+//
+// Use the ATOMIC_SHORT_PAIR macro (see macros.hpp) to get the desired alignment.
+struct Atomic::AddShortUsingInt VALUE_OBJ_CLASS_SPEC {
+  template<typename T>
+  T operator()(T add_value, T volatile* dest) const;
+};
+
 // Define the class before including platform file, which may specialize
 // the operator definition.  No generic definition of specializations
 // of the operator template are provided, nor are there any generic
 // specializations of the class.  The platform file is responsible for
 // providing those.

@@ -383,31 +398,20 @@
     CI addend = add_value;
     return PlatformAdd<sizeof(P*)>()(addend, dest);
   }
 };
 
-// Most platforms do not support atomic add on a 2-byte value. However,
-// if the value occupies the most significant 16 bits of an aligned 32-bit
-// word, then we can do this with an atomic add of (add_value << 16)
-// to the 32-bit word.
-//
-// The least significant parts of this 32-bit word will never be affected, even
-// in case of overflow/underflow.
-//
-// Use the ATOMIC_SHORT_PAIR macro (see macros.hpp) to get the desired alignment.
-template<>
-struct Atomic::AddImpl<jshort, jshort> VALUE_OBJ_CLASS_SPEC {
-  jshort operator()(jshort add_value, jshort volatile* dest) const {
+template<typename T>
+T Atomic::AddShortUsingInt::operator()(T add_value, T volatile* dest) const {
 #ifdef VM_LITTLE_ENDIAN
     assert((intx(dest) & 0x03) == 0x02, "wrong alignment");
-    jint new_value = Atomic::add(add_value << 16, (volatile jint*)(dest-1));
+  uint32_t new_value = Atomic::add(uint32_t(add_value) << 16, (volatile uint32_t*)(dest-1));
 #else
     assert((intx(dest) & 0x03) == 0x00, "wrong alignment");
-    jint new_value = Atomic::add(add_value << 16, (volatile jint*)(dest));
+  uint32_t new_value = Atomic::add(uint32_t(add_value) << 16, (volatile uint32_t*)(dest));
 #endif
-    return (jshort)(new_value >> 16); // preserves sign
-  }
+  return T(new_value >> 16); // preserves sign
 };
 
 template<typename Derived>
 template<typename I, typename D>
 inline D Atomic::FetchAndAdd<Derived>::operator()(I add_value, D volatile* dest) const {
< prev index next >