diff options
author | rmcilroy@chromium.org <rmcilroy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-07 13:54:56 +0000 |
---|---|---|
committer | rmcilroy@chromium.org <rmcilroy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-07 13:54:56 +0000 |
commit | f63b95e00dad12a107123445d5ccfe19eb631c7a (patch) | |
tree | 2c3ab25fc34a8c8de92f2da5656e4bcae2107235 /third_party/protobuf | |
parent | 4edaf7ec4e464f4430628d167be3d2beb8a40ec9 (diff) | |
download | chromium_src-f63b95e00dad12a107123445d5ccfe19eb631c7a.zip chromium_src-f63b95e00dad12a107123445d5ccfe19eb631c7a.tar.gz chromium_src-f63b95e00dad12a107123445d5ccfe19eb631c7a.tar.bz2 |
Cherry pick r523 and r524 from upstream protobuf
Fixes a bug in Arm64 atomicops and improve Arm64 atomic operations.
BUG=354405
Review URL: https://codereview.chromium.org/263383004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@268736 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party/protobuf')
-rw-r--r-- | third_party/protobuf/README.chromium | 2 | ||||
-rw-r--r-- | third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h | 153 |
2 files changed, 52 insertions, 103 deletions
diff --git a/third_party/protobuf/README.chromium b/third_party/protobuf/README.chromium index ab2cff4..298c207 100644 --- a/third_party/protobuf/README.chromium +++ b/third_party/protobuf/README.chromium @@ -31,6 +31,8 @@ Revision 512 was cherry-picked from upstream. Revision 516 was cherry-picked from upstream. Revision 517 was cherry-picked from upstream. Revision 522 was cherry-picked from upstream. +Revision 523 was cherry-picked from upstream. +Revision 524 was cherry-picked from upstream. Notes about Java: We have not forked the Java version of protobuf-lite, so the Java version does diff --git a/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h b/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h index c13cddb..fe9727a 100644 --- a/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h +++ b/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h @@ -38,12 +38,16 @@ namespace protobuf { namespace internal { inline void MemoryBarrier() { - __asm__ __volatile__ ( // NOLINT - "dmb ish \n\t" // Data memory barrier. - ::: "memory" - ); // NOLINT + __asm__ __volatile__ ("dmb ish" ::: "memory"); // NOLINT } +// NoBarrier versions of the operation include "memory" in the clobber list. +// This is not required for direct usage of the NoBarrier versions of the +// operations. However this is required for correctness when they are used as +// part of the Acquire or Release versions, to ensure that nothing from outside +// the call is reordered between the operation and the memory barrier. This does +// not change the code generated, so has no or minimal impact on the +// NoBarrier operations. inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, Atomic32 old_value, @@ -59,13 +63,12 @@ inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, "stxr %w[temp], %w[new_value], %[ptr] \n\t" // Try to store the new value. "cbnz %w[temp], 0b \n\t" // Retry if it did not work. "1: \n\t" - "clrex \n\t" // In case we didn't swap. : [prev]"=&r" (prev), [temp]"=&r" (temp), [ptr]"+Q" (*ptr) - : [old_value]"r" (old_value), + : [old_value]"IJr" (old_value), [new_value]"r" (new_value) - : "memory", "cc" + : "cc", "memory" ); // NOLINT return prev; @@ -105,7 +108,7 @@ inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, : [result]"=&r" (result), [temp]"=&r" (temp), [ptr]"+Q" (*ptr) - : [increment]"r" (increment) + : [increment]"IJr" (increment) : "memory" ); // NOLINT @@ -124,28 +127,8 @@ inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, Atomic32 old_value, Atomic32 new_value) { - Atomic32 prev; - int32_t temp; - - __asm__ __volatile__ ( // NOLINT - "0: \n\t" - "ldxr %w[prev], %[ptr] \n\t" // Load the previous value. - "cmp %w[prev], %w[old_value] \n\t" - "bne 1f \n\t" - "stxr %w[temp], %w[new_value], %[ptr] \n\t" // Try to store the new value. - "cbnz %w[temp], 0b \n\t" // Retry if it did not work. - "dmb ish \n\t" // Data memory barrier. - "1: \n\t" - // If the compare failed the 'dmb' is unnecessary, but we still need a - // 'clrex'. - "clrex \n\t" - : [prev]"=&r" (prev), - [temp]"=&r" (temp), - [ptr]"+Q" (*ptr) - : [old_value]"r" (old_value), - [new_value]"r" (new_value) - : "memory", "cc" - ); // NOLINT + Atomic32 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value); + MemoryBarrier(); return prev; } @@ -153,28 +136,8 @@ inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, Atomic32 old_value, Atomic32 new_value) { - Atomic32 prev; - int32_t temp; - MemoryBarrier(); - - __asm__ __volatile__ ( // NOLINT - "0: \n\t" - "ldxr %w[prev], %[ptr] \n\t" // Load the previous value. - "cmp %w[prev], %w[old_value] \n\t" - "bne 1f \n\t" - "stxr %w[temp], %w[new_value], %[ptr] \n\t" // Try to store the new value. - "cbnz %w[temp], 0b \n\t" // Retry if it did not work. - "1: \n\t" - // If the compare failed the we still need a 'clrex'. - "clrex \n\t" - : [prev]"=&r" (prev), - [temp]"=&r" (temp), - [ptr]"+Q" (*ptr) - : [old_value]"r" (old_value), - [new_value]"r" (new_value) - : "memory", "cc" - ); // NOLINT + Atomic32 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value); return prev; } @@ -189,8 +152,12 @@ inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { } inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { - MemoryBarrier(); - *ptr = value; + __asm__ __volatile__ ( // NOLINT + "stlr %w[value], %[ptr] \n\t" + : [ptr]"=Q" (*ptr) + : [value]"r" (value) + : "memory" + ); // NOLINT } inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { @@ -198,8 +165,15 @@ inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { } inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { - Atomic32 value = *ptr; - MemoryBarrier(); + Atomic32 value; + + __asm__ __volatile__ ( // NOLINT + "ldar %w[value], %[ptr] \n\t" + : [value]"=r" (value) + : [ptr]"Q" (*ptr) + : "memory" + ); // NOLINT + return value; } @@ -225,13 +199,12 @@ inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, "stxr %w[temp], %[new_value], %[ptr] \n\t" "cbnz %w[temp], 0b \n\t" "1: \n\t" - "clrex \n\t" : [prev]"=&r" (prev), [temp]"=&r" (temp), [ptr]"+Q" (*ptr) - : [old_value]"r" (old_value), + : [old_value]"IJr" (old_value), [new_value]"r" (new_value) - : "memory", "cc" + : "cc", "memory" ); // NOLINT return prev; @@ -271,7 +244,7 @@ inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, : [result]"=&r" (result), [temp]"=&r" (temp), [ptr]"+Q" (*ptr) - : [increment]"r" (increment) + : [increment]"IJr" (increment) : "memory" ); // NOLINT @@ -290,26 +263,8 @@ inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, Atomic64 old_value, Atomic64 new_value) { - Atomic64 prev; - int32_t temp; - - __asm__ __volatile__ ( // NOLINT - "0: \n\t" - "ldxr %[prev], %[ptr] \n\t" - "cmp %[prev], %[old_value] \n\t" - "bne 1f \n\t" - "stxr %w[temp], %[new_value], %[ptr] \n\t" - "cbnz %w[temp], 0b \n\t" - "dmb ish \n\t" - "1: \n\t" - "clrex \n\t" - : [prev]"=&r" (prev), - [temp]"=&r" (temp), - [ptr]"+Q" (*ptr) - : [old_value]"r" (old_value), - [new_value]"r" (new_value) - : "memory", "cc" - ); // NOLINT + Atomic64 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value); + MemoryBarrier(); return prev; } @@ -317,27 +272,8 @@ inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, Atomic64 old_value, Atomic64 new_value) { - Atomic64 prev; - int32_t temp; - MemoryBarrier(); - - __asm__ __volatile__ ( // NOLINT - "0: \n\t" - "ldxr %[prev], %[ptr] \n\t" - "cmp %[prev], %[old_value] \n\t" - "bne 1f \n\t" - "stxr %w[temp], %[new_value], %[ptr] \n\t" - "cbnz %w[temp], 0b \n\t" - "1: \n\t" - "clrex \n\t" - : [prev]"=&r" (prev), - [temp]"=&r" (temp), - [ptr]"+Q" (*ptr) - : [old_value]"r" (old_value), - [new_value]"r" (new_value) - : "memory", "cc" - ); // NOLINT + Atomic64 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value); return prev; } @@ -352,8 +288,12 @@ inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) { } inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { - MemoryBarrier(); - *ptr = value; + __asm__ __volatile__ ( // NOLINT + "stlr %x[value], %[ptr] \n\t" + : [ptr]"=Q" (*ptr) + : [value]"r" (value) + : "memory" + ); // NOLINT } inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { @@ -361,8 +301,15 @@ inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { } inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { - Atomic64 value = *ptr; - MemoryBarrier(); + Atomic64 value; + + __asm__ __volatile__ ( // NOLINT + "ldar %x[value], %[ptr] \n\t" + : [value]"=r" (value) + : [ptr]"Q" (*ptr) + : "memory" + ); // NOLINT + return value; } |