Bug 1146817 - Add float and double test cases for loadSafeWhenRacy / storeSafeWhenRacy. r=sstangl

--HG--
extra : source : bdd79a98de6a8d1bb3248d6e857ed4c3e875bf1e
extra : amend_source : 0fa9f4c1b135c8f7cb5dc3fe2b45c353aa752796
This commit is contained in:
Lars T Hansen 2017-09-05 13:48:53 +02:00
parent 6fa93e8121
commit 7692df0ca3
3 changed files with 87 additions and 7 deletions

View File

@ -140,10 +140,10 @@ class AtomicOperations
template<typename T>
static inline void storeSafeWhenRacy(T* addr, T val);
// Replacement for memcpy().
// Replacement for memcpy(). No access-atomicity guarantees.
static inline void memcpySafeWhenRacy(void* dest, const void* src, size_t nbytes);
// Replacement for memmove().
// Replacement for memmove(). No access-atomicity guarantees.
static inline void memmoveSafeWhenRacy(void* dest, const void* src, size_t nbytes);
public:
@ -287,10 +287,9 @@ class AtomicOperations
#endif
};
/* A data type representing a lock on some region of a
* SharedArrayRawBuffer's memory, to be used only when the hardware
* does not provide necessary atomicity (eg, float64 access on ARMv6
* and some ARMv7 systems).
/* A data type representing a lock on some region of a SharedArrayRawBuffer's
* memory, to be used only when the hardware does not provide necessary
* atomicity.
*/
class RegionLock
{
@ -299,7 +298,7 @@ class RegionLock
/* Addr is the address to be locked, nbytes the number of bytes we
* need to lock. The lock that is taken may cover a larger range
* of bytes.
* of bytes, indeed it may cover all of memory.
*/
template<size_t nbytes>
void acquire(void* addr);

View File

@ -354,6 +354,8 @@ js::jit::AtomicOperations::loadSafeWhenRacy(T* addr)
namespace js { namespace jit {
// For double and float there are no access-atomicity guarantees so go directly
// to the default implementation.
MSC_RACYLOADOP(int64_t)
MSC_RACYLOADOP(uint64_t)
@ -389,6 +391,8 @@ namespace js { namespace jit {
} \
}
// For double and float there are no access-atomicity guarantees so go directly
// to the default implementation.
MSC_RACYSTOREOP(int64_t)
MSC_RACYSTOREOP(uint64_t)

View File

@ -227,4 +227,81 @@ BEGIN_TEST(testAtomicOperationsI64)
}
END_TEST(testAtomicOperationsI64)
// T is the primitive float type we're testing, and A and B are references to
// constant bindings holding values of that type.
//
// Stay away from 0, NaN, infinities, and denormals.
#define ATOMIC_FLOAT_TESTS(T, A, B) \
T* q = (T*)hidePointerValue((void*)atomicMem); \
*q = A; \
SharedMem<T*> p = SharedMem<T*>::shared((T*)hidePointerValue((T*)atomicMem)); \
CHECK(*q == A); \
CHECK(jit::AtomicOperations::loadSafeWhenRacy(p) == A); \
jit::AtomicOperations::storeSafeWhenRacy(p, B); \
CHECK(*q == B); \
T* q2 = (T*)hidePointerValue((void*)atomicMem2); \
SharedMem<T*> p2 = SharedMem<T*>::shared((T*)hidePointerValue((void*)atomicMem2)); \
*q = A; \
*q2 = B; \
jit::AtomicOperations::memcpySafeWhenRacy(p2, p, sizeof(T)); \
CHECK(*q2 == A); \
*q = A; \
*q2 = B; \
jit::AtomicOperations::memcpySafeWhenRacy(p2, p.unwrap(), sizeof(T));\
CHECK(*q2 == A); \
*q = A; \
*q2 = B; \
jit::AtomicOperations::memcpySafeWhenRacy(p2.unwrap(), p, sizeof(T));\
CHECK(*q2 == A); \
*q = A; \
*q2 = B; \
jit::AtomicOperations::memmoveSafeWhenRacy(p2, p, sizeof(T)); \
CHECK(*q2 == A); \
*q = A; \
*q2 = B; \
jit::AtomicOperations::podCopySafeWhenRacy(p2, p, 1); \
CHECK(*q2 == A); \
*q = A; \
*q2 = B; \
jit::AtomicOperations::podMoveSafeWhenRacy(p2, p, 1); \
CHECK(*q2 == A); \
return true
BEGIN_TEST(testAtomicOperationsF32)
{
const float A(123.25);
const float B(-987.75);
ATOMIC_FLOAT_TESTS(float, A, B);
}
END_TEST(testAtomicOperationsF32)
BEGIN_TEST(testAtomicOperationsF64)
{
const double A(123.25);
const double B(-987.75);
ATOMIC_FLOAT_TESTS(double, A, B);
}
END_TEST(testAtomicOperationsF64)
#define ATOMIC_CLAMPED_TESTS(T, A, B) \
T* q = (T*)hidePointerValue((void*)atomicMem); \
*q = A; \
SharedMem<T*> p = SharedMem<T*>::shared((T*)hidePointerValue((T*)atomicMem)); \
CHECK(*q == A); \
CHECK(jit::AtomicOperations::loadSafeWhenRacy(p) == A); \
jit::AtomicOperations::storeSafeWhenRacy(p, B); \
CHECK(*q == B); \
return true
BEGIN_TEST(testAtomicOperationsU8Clamped)
{
const uint8_clamped A(0xab);
const uint8_clamped B(0x37);
ATOMIC_CLAMPED_TESTS(uint8_clamped, A, B);
}
END_TEST(testAtomicOperationsU8Clamped)
#undef ATOMIC_TESTS
#undef ATOMIC_FLOAT_TESTS
#undef ATOMIC_CLAMPED_TESTS