Bug 1311088 - Part 1: Add mozilla::SpecificNaNBits and JS::detail::CanonicalizedNaNBits. r=jwalden
authorTooru Fujisawa <arai_a@mac.com>
Sat, 29 Oct 2016 01:47:30 +0900
changeset 362815 c8357a5b2431329993612ecd1095bff70f1d1911
parent 362814 83ab2e59b7b537e420ba8aab75544a287686476a
child 362816 9581faa40dcaf5b090e12d581efc08deb839c8cd
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-beta@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwalden
bugs1311088
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1311088 - Part 1: Add mozilla::SpecificNaNBits and JS::detail::CanonicalizedNaNBits. r=jwalden
js/public/Value.h
mfbt/FloatingPoint.h
--- a/js/public/Value.h
+++ b/js/public/Value.h
@@ -219,26 +219,39 @@ typedef enum JSWhyMagic
     JS_WHY_MAGIC_COUNT
 } JSWhyMagic;
 
 namespace JS {
 
 static inline constexpr JS::Value UndefinedValue();
 static inline JS::Value PoisonedObjectValue(JSObject* obj);
 
+namespace detail {
+
+constexpr int CanonicalizedNaNSignBit = 0;
+constexpr uint64_t CanonicalizedNaNSignificand = 0x8000000000000ULL;
+
+constexpr uint64_t CanonicalizedNaNBits =
+    mozilla::SpecificNaNBits<double,
+                             detail::CanonicalizedNaNSignBit,
+                             detail::CanonicalizedNaNSignificand>::value;
+
+} // namespace detail
+
 /**
  * Returns a generic quiet NaN value, with all payload bits set to zero.
  *
  * Among other properties, this NaN's bit pattern conforms to JS::Value's
  * bit pattern restrictions.
  */
 static MOZ_ALWAYS_INLINE double
 GenericNaN()
 {
-  return mozilla::SpecificNaN<double>(0, 0x8000000000000ULL);
+  return mozilla::SpecificNaN<double>(detail::CanonicalizedNaNSignBit,
+                                      detail::CanonicalizedNaNSignificand);
 }
 
 /* MSVC with PGO miscompiles this function. */
 #if defined(_MSC_VER)
 # pragma optimize("g", off)
 #endif
 static inline double
 CanonicalizeNaN(double d)
@@ -999,21 +1012,21 @@ Int32Value(int32_t i32)
 static inline Value
 DoubleValue(double dbl)
 {
     Value v;
     v.setDouble(dbl);
     return v;
 }
 
-static inline constexpr Value
+static inline Value
 CanonicalizedDoubleValue(double d)
 {
     return MOZ_UNLIKELY(mozilla::IsNaN(d))
-           ? Value::fromRawBits(0x7FF8000000000000ULL)
+           ? Value::fromRawBits(detail::CanonicalizedNaNBits)
            : Value::fromDouble(d);
 }
 
 static inline Value
 DoubleNaNValue()
 {
     Value v;
     v.setNaN();
--- a/mfbt/FloatingPoint.h
+++ b/mfbt/FloatingPoint.h
@@ -251,16 +251,36 @@ NegativeInfinity()
   /*
    * Negative infinity has all exponent bits set, sign bit set to 1, and no
    * significand.
    */
   typedef FloatingPoint<T> Traits;
   return BitwiseCast<T>(Traits::kSignBit | Traits::kExponentBits);
 }
 
+/**
+ * Computes the bit pattern for a NaN with the specified sign bit and
+ * significand bits.
+ */
+template<typename T,
+         int SignBit,
+         typename FloatingPoint<T>::Bits Significand>
+struct SpecificNaNBits
+{
+  using Traits = FloatingPoint<T>;
+
+  static_assert(SignBit == 0 || SignBit == 1, "bad sign bit");
+  static_assert((Significand & ~Traits::kSignificandBits) == 0,
+                "significand must only have significand bits set");
+  static_assert(Significand & Traits::kSignificandBits,
+                "significand must be nonzero");
+
+  static constexpr typename Traits::Bits value =
+    (SignBit * Traits::kSignBit) | Traits::kExponentBits | Significand;
+};
 
 /**
  * Constructs a NaN value with the specified sign bit and significand bits.
  *
  * There is also a variant that returns the value directly.  In most cases, the
  * two variants should be identical.  However, in the specific case of x86
  * chips, the behavior differs: returning floating-point values directly is done
  * through the x87 stack, and x87 loads and stores turn signaling NaNs into