diff --git a/src/os_cpu/linux_x86/vm/atomic_linux_x86.inline.hpp b/src/os_cpu/linux_x86/vm/atomic_linux_x86.inline.hpp
--- a/src/os_cpu/linux_x86/vm/atomic_linux_x86.inline.hpp
+++ b/src/os_cpu/linux_x86/vm/atomic_linux_x86.inline.hpp
@@ -43,36 +43,13 @@
 inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; }
 inline void Atomic::store_ptr(void*    store_value, volatile void*     dest) { *(void* volatile *)dest = store_value; }
 
-
 // Adding a lock prefix to an instruction on MP machine
 #define LOCK_IF_MP(mp) "cmp $0, " #mp "; je 1f; lock; 1: "
 
-inline jint     Atomic::add    (jint     add_value, volatile jint*     dest) {
-  jint addend = add_value;
-  int mp = os::is_MP();
-  __asm__ volatile (  LOCK_IF_MP(%3) "xaddl %0,(%2)"
-                    : "=r" (addend)
-                    : "0" (addend), "r" (dest), "r" (mp)
-                    : "cc", "memory");
-  return addend + add_value;
-}
-
-inline void Atomic::inc    (volatile jint*     dest) {
-  int mp = os::is_MP();
-  __asm__ volatile (LOCK_IF_MP(%1) "addl $1,(%0)" :
-                    : "r" (dest), "r" (mp) : "cc", "memory");
-}
-
 inline void Atomic::inc_ptr(volatile void*     dest) {
   inc_ptr((volatile intptr_t*)dest);
 }
 
-inline void Atomic::dec    (volatile jint*     dest) {
-  int mp = os::is_MP();
-  __asm__ volatile (LOCK_IF_MP(%1) "subl $1,(%0)" :
-                    : "r" (dest), "r" (mp) : "cc", "memory");
-}
-
 inline void Atomic::dec_ptr(volatile void*     dest) {
   dec_ptr((volatile intptr_t*)dest);
 }
@@ -217,4 +194,29 @@
 
 #endif // AMD64
 
+inline uint16_t AtomicOps::add_and_fetch(volatile uint16_t *addr, uint16_t value) {
+  return __sync_add_and_fetch(addr, value);
+}
+
+inline uint32_t AtomicOps::add_and_fetch(volatile uint32_t *addr, uint32_t value) {
+  return __sync_add_and_fetch(addr, value);
+}
+
+inline uint64_t AtomicOps::add_and_fetch(volatile uint64_t *addr, uint64_t value) {
+  return __sync_add_and_fetch(addr, value);
+}
+
+inline uint16_t AtomicOps::sub_and_fetch(volatile uint16_t *addr, uint16_t value) {
+  return __sync_sub_and_fetch(addr, value);
+}
+
+inline uint32_t AtomicOps::sub_and_fetch(volatile uint32_t *addr, uint32_t value) {
+  return __sync_sub_and_fetch(addr, value);
+}
+
+inline uint64_t AtomicOps::sub_and_fetch(volatile uint64_t *addr, uint64_t value) {
+  return __sync_sub_and_fetch(addr, value);
+}
+
+
 #endif // OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_INLINE_HPP
diff --git a/src/share/vm/runtime/atomic.hpp b/src/share/vm/runtime/atomic.hpp
--- a/src/share/vm/runtime/atomic.hpp
+++ b/src/share/vm/runtime/atomic.hpp
@@ -27,6 +27,8 @@
 
 #include "memory/allocation.hpp"
 
+#include "atomic_template.hpp"
+
 class Atomic : AllStatic {
  public:
   // Atomic operations on jlong types are not available on all 32-bit
@@ -56,21 +58,32 @@
   inline static jlong load(volatile jlong* src);
 
   // Atomically add to a location, return updated value
-  inline static jint     add    (jint     add_value, volatile jint*     dest);
   inline static intptr_t add_ptr(intptr_t add_value, volatile intptr_t* dest);
   inline static void*    add_ptr(intptr_t add_value, volatile void*     dest);
-  // See comment above about using jlong atomics on 32-bit platforms
-         static jlong    add    (jlong    add_value, volatile jlong*    dest);
 
+  // type generic Atomic::add
+  template <typename T>
+  static inline T add(T value, volatile T* addr) {
+    typedef widthtype<op<sizeof(T)>::WIDTH> cast;
+    return op<sizeof(T)>::add_atomic(cast::ptrcast(addr), cast::cast(value));
+  }
   // Atomically increment location
-  inline static void inc    (volatile jint*     dest);
-         static void inc    (volatile jshort*   dest);
+  // type generic Atomic::inc
+  template <typename T>
+  static inline void inc(volatile T* addr) {
+    typedef widthtype<op<sizeof(T)>::WIDTH> cast;
+    op<sizeof(T)>::add_atomic(cast::ptrcast(addr), 1);
+  }
   inline static void inc_ptr(volatile intptr_t* dest);
   inline static void inc_ptr(volatile void*     dest);
 
   // Atomically decrement a location
-  inline static void dec    (volatile jint*     dest);
-         static void dec    (volatile jshort*    dest);
+  // type generic Atomic::dec
+  template <typename T>
+  static inline void dec(volatile T* addr) {
+    typedef widthtype<op<sizeof(T)>::WIDTH> cast;
+    op<sizeof(T)>::sub_atomic(cast::ptrcast(addr), 1);
+  }
   inline static void dec_ptr(volatile intptr_t* dest);
   inline static void dec_ptr(volatile void*     dest);
 
diff --git a/src/share/vm/runtime/atomic.inline.hpp b/src/share/vm/runtime/atomic.inline.hpp
--- a/src/share/vm/runtime/atomic.inline.hpp
+++ b/src/share/vm/runtime/atomic.inline.hpp
@@ -27,6 +27,7 @@
 
 #include "runtime/atomic.hpp"
 
+
 // Linux
 #ifdef TARGET_OS_ARCH_linux_x86
 # include "atomic_linux_x86.inline.hpp"
@@ -70,4 +71,5 @@
 # include "atomic_bsd_zero.inline.hpp"
 #endif
 
+
 #endif // SHARE_VM_RUNTIME_ATOMIC_INLINE_HPP
diff --git a/src/share/vm/runtime/atomic_template.hpp b/src/share/vm/runtime/atomic_template.hpp
new file mode 100644
--- /dev/null
+++ b/src/share/vm/runtime/atomic_template.hpp
@@ -0,0 +1,97 @@
+#ifndef SHARE_VM_RUNTIME_ATOMIC_TEMPLATE_HPP
+#define SHARE_VM_RUNTIME_ATOMIC_TEMPLATE_HPP
+
+class AtomicOps : AllStatic {
+public:
+  inline static uint16_t add_and_fetch(volatile uint16_t *addr, uint16_t value);
+  inline static uint32_t add_and_fetch(volatile uint32_t *addr, uint32_t value);
+  inline static uint64_t add_and_fetch(volatile uint64_t *addr, uint64_t value);
+
+  inline static uint16_t sub_and_fetch(volatile uint16_t *addr, uint16_t value);
+  inline static uint32_t sub_and_fetch(volatile uint32_t *addr, uint32_t value);
+  inline static uint64_t sub_and_fetch(volatile uint64_t *addr, uint64_t value);
+};
+
+// empty placeholder for op
+template <size_t W>
+struct op {
+};
+
+// begin type helpers
+template<size_t W>
+struct widthtype {
+  typedef typename op<W>::type type;
+  typedef typename op<W>::ptrtype ptrtype;
+
+  // help cast correctly
+  template<typename T>
+  static type cast(T value) {
+    return static_cast<type>(value);
+  }
+
+  // help cast the pointer correctly
+  template<typename T>
+  static ptrtype ptrcast(T value) {
+    return reinterpret_cast<ptrtype>(value);
+  }
+};
+
+// contains all atomic operations for 2 byte types
+template<>
+struct op<2> {
+  enum { WIDTH = 2 };
+
+  // use uint16_t as the generic type for 2 byte types
+  typedef uint16_t type;
+  typedef volatile type *ptrtype;
+
+  static uint16_t add_atomic(volatile uint16_t *dest, uint16_t add_value) {
+    return AtomicOps::add_and_fetch(dest, add_value);
+  }
+
+  static void sub_atomic(volatile uint16_t* dest, uint16_t sub_value) {
+    AtomicOps::sub_and_fetch(dest, sub_value);
+  }
+
+};
+
+// contains all atomic operations for 4 byte types
+template<>
+struct op<4> {
+  enum { WIDTH = 4 };
+
+  // use uint32_t as the generic type for 4 byte types
+  typedef uint32_t type;
+  typedef volatile type *ptrtype;
+
+  static uint32_t add_atomic(volatile uint32_t *dest, uint32_t add_value) {
+    return AtomicOps::add_and_fetch(dest, add_value);
+  }
+
+  static void sub_atomic(volatile uint32_t* dest, uint32_t sub_value) {
+    AtomicOps::sub_and_fetch(dest, sub_value);
+  }
+
+};
+
+// contains all atomic operations for 8 byte types
+template<>
+struct op<8> {
+  enum { WIDTH = 8 };
+
+  // use uint64_t as the generic type for 8 byte types
+  typedef uint64_t type;
+  typedef volatile type *ptrtype;
+
+  static uint64_t add_atomic(volatile uint64_t* dest, uint64_t add_value) {
+    return AtomicOps::add_and_fetch(dest, add_value);
+  }
+
+  static void sub_atomic(volatile uint64_t* dest, uint64_t sub_value) {
+    AtomicOps::sub_and_fetch(dest, sub_value);
+  }
+
+};
+
+
+#endif
