mfbt/double-conversion/ieee.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 // Copyright 2012 the V8 project authors. All rights reserved.
     2 // Redistribution and use in source and binary forms, with or without
     3 // modification, are permitted provided that the following conditions are
     4 // met:
     5 //
     6 //     * Redistributions of source code must retain the above copyright
     7 //       notice, this list of conditions and the following disclaimer.
     8 //     * Redistributions in binary form must reproduce the above
     9 //       copyright notice, this list of conditions and the following
    10 //       disclaimer in the documentation and/or other materials provided
    11 //       with the distribution.
    12 //     * Neither the name of Google Inc. nor the names of its
    13 //       contributors may be used to endorse or promote products derived
    14 //       from this software without specific prior written permission.
    15 //
    16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    28 #ifndef DOUBLE_CONVERSION_DOUBLE_H_
    29 #define DOUBLE_CONVERSION_DOUBLE_H_
    31 #include "diy-fp.h"
    33 namespace double_conversion {
    35 // We assume that doubles and uint64_t have the same endianness.
    36 static uint64_t double_to_uint64(double d) { return BitCast<uint64_t>(d); }
    37 static double uint64_to_double(uint64_t d64) { return BitCast<double>(d64); }
    38 static uint32_t float_to_uint32(float f) { return BitCast<uint32_t>(f); }
    39 static float uint32_to_float(uint32_t d32) { return BitCast<float>(d32); }
    41 // Helper functions for doubles.
    42 class Double {
    43  public:
    44   static const uint64_t kSignMask = UINT64_2PART_C(0x80000000, 00000000);
    45   static const uint64_t kExponentMask = UINT64_2PART_C(0x7FF00000, 00000000);
    46   static const uint64_t kSignificandMask = UINT64_2PART_C(0x000FFFFF, FFFFFFFF);
    47   static const uint64_t kHiddenBit = UINT64_2PART_C(0x00100000, 00000000);
    48   static const int kPhysicalSignificandSize = 52;  // Excludes the hidden bit.
    49   static const int kSignificandSize = 53;
    51   Double() : d64_(0) {}
    52   explicit Double(double d) : d64_(double_to_uint64(d)) {}
    53   explicit Double(uint64_t d64) : d64_(d64) {}
    54   explicit Double(DiyFp diy_fp)
    55     : d64_(DiyFpToUint64(diy_fp)) {}
    57   // The value encoded by this Double must be greater or equal to +0.0.
    58   // It must not be special (infinity, or NaN).
    59   DiyFp AsDiyFp() const {
    60     ASSERT(Sign() > 0);
    61     ASSERT(!IsSpecial());
    62     return DiyFp(Significand(), Exponent());
    63   }
    65   // The value encoded by this Double must be strictly greater than 0.
    66   DiyFp AsNormalizedDiyFp() const {
    67     ASSERT(value() > 0.0);
    68     uint64_t f = Significand();
    69     int e = Exponent();
    71     // The current double could be a denormal.
    72     while ((f & kHiddenBit) == 0) {
    73       f <<= 1;
    74       e--;
    75     }
    76     // Do the final shifts in one go.
    77     f <<= DiyFp::kSignificandSize - kSignificandSize;
    78     e -= DiyFp::kSignificandSize - kSignificandSize;
    79     return DiyFp(f, e);
    80   }
    82   // Returns the double's bit as uint64.
    83   uint64_t AsUint64() const {
    84     return d64_;
    85   }
    87   // Returns the next greater double. Returns +infinity on input +infinity.
    88   double NextDouble() const {
    89     if (d64_ == kInfinity) return Double(kInfinity).value();
    90     if (Sign() < 0 && Significand() == 0) {
    91       // -0.0
    92       return 0.0;
    93     }
    94     if (Sign() < 0) {
    95       return Double(d64_ - 1).value();
    96     } else {
    97       return Double(d64_ + 1).value();
    98     }
    99   }
   101   double PreviousDouble() const {
   102     if (d64_ == (kInfinity | kSignMask)) return -Double::Infinity();
   103     if (Sign() < 0) {
   104       return Double(d64_ + 1).value();
   105     } else {
   106       if (Significand() == 0) return -0.0;
   107       return Double(d64_ - 1).value();
   108     }
   109   }
   111   int Exponent() const {
   112     if (IsDenormal()) return kDenormalExponent;
   114     uint64_t d64 = AsUint64();
   115     int biased_e =
   116         static_cast<int>((d64 & kExponentMask) >> kPhysicalSignificandSize);
   117     return biased_e - kExponentBias;
   118   }
   120   uint64_t Significand() const {
   121     uint64_t d64 = AsUint64();
   122     uint64_t significand = d64 & kSignificandMask;
   123     if (!IsDenormal()) {
   124       return significand + kHiddenBit;
   125     } else {
   126       return significand;
   127     }
   128   }
   130   // Returns true if the double is a denormal.
   131   bool IsDenormal() const {
   132     uint64_t d64 = AsUint64();
   133     return (d64 & kExponentMask) == 0;
   134   }
   136   // We consider denormals not to be special.
   137   // Hence only Infinity and NaN are special.
   138   bool IsSpecial() const {
   139     uint64_t d64 = AsUint64();
   140     return (d64 & kExponentMask) == kExponentMask;
   141   }
   143   bool IsNan() const {
   144     uint64_t d64 = AsUint64();
   145     return ((d64 & kExponentMask) == kExponentMask) &&
   146         ((d64 & kSignificandMask) != 0);
   147   }
   149   bool IsInfinite() const {
   150     uint64_t d64 = AsUint64();
   151     return ((d64 & kExponentMask) == kExponentMask) &&
   152         ((d64 & kSignificandMask) == 0);
   153   }
   155   int Sign() const {
   156     uint64_t d64 = AsUint64();
   157     return (d64 & kSignMask) == 0? 1: -1;
   158   }
   160   // Precondition: the value encoded by this Double must be greater or equal
   161   // than +0.0.
   162   DiyFp UpperBoundary() const {
   163     ASSERT(Sign() > 0);
   164     return DiyFp(Significand() * 2 + 1, Exponent() - 1);
   165   }
   167   // Computes the two boundaries of this.
   168   // The bigger boundary (m_plus) is normalized. The lower boundary has the same
   169   // exponent as m_plus.
   170   // Precondition: the value encoded by this Double must be greater than 0.
   171   void NormalizedBoundaries(DiyFp* out_m_minus, DiyFp* out_m_plus) const {
   172     ASSERT(value() > 0.0);
   173     DiyFp v = this->AsDiyFp();
   174     DiyFp m_plus = DiyFp::Normalize(DiyFp((v.f() << 1) + 1, v.e() - 1));
   175     DiyFp m_minus;
   176     if (LowerBoundaryIsCloser()) {
   177       m_minus = DiyFp((v.f() << 2) - 1, v.e() - 2);
   178     } else {
   179       m_minus = DiyFp((v.f() << 1) - 1, v.e() - 1);
   180     }
   181     m_minus.set_f(m_minus.f() << (m_minus.e() - m_plus.e()));
   182     m_minus.set_e(m_plus.e());
   183     *out_m_plus = m_plus;
   184     *out_m_minus = m_minus;
   185   }
   187   bool LowerBoundaryIsCloser() const {
   188     // The boundary is closer if the significand is of the form f == 2^p-1 then
   189     // the lower boundary is closer.
   190     // Think of v = 1000e10 and v- = 9999e9.
   191     // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but
   192     // at a distance of 1e8.
   193     // The only exception is for the smallest normal: the largest denormal is
   194     // at the same distance as its successor.
   195     // Note: denormals have the same exponent as the smallest normals.
   196     bool physical_significand_is_zero = ((AsUint64() & kSignificandMask) == 0);
   197     return physical_significand_is_zero && (Exponent() != kDenormalExponent);
   198   }
   200   double value() const { return uint64_to_double(d64_); }
   202   // Returns the significand size for a given order of magnitude.
   203   // If v = f*2^e with 2^p-1 <= f <= 2^p then p+e is v's order of magnitude.
   204   // This function returns the number of significant binary digits v will have
   205   // once it's encoded into a double. In almost all cases this is equal to
   206   // kSignificandSize. The only exceptions are denormals. They start with
   207   // leading zeroes and their effective significand-size is hence smaller.
   208   static int SignificandSizeForOrderOfMagnitude(int order) {
   209     if (order >= (kDenormalExponent + kSignificandSize)) {
   210       return kSignificandSize;
   211     }
   212     if (order <= kDenormalExponent) return 0;
   213     return order - kDenormalExponent;
   214   }
   216   static double Infinity() {
   217     return Double(kInfinity).value();
   218   }
   220   static double NaN() {
   221     return Double(kNaN).value();
   222   }
   224  private:
   225   static const int kExponentBias = 0x3FF + kPhysicalSignificandSize;
   226   static const int kDenormalExponent = -kExponentBias + 1;
   227   static const int kMaxExponent = 0x7FF - kExponentBias;
   228   static const uint64_t kInfinity = UINT64_2PART_C(0x7FF00000, 00000000);
   229   static const uint64_t kNaN = UINT64_2PART_C(0x7FF80000, 00000000);
   231   const uint64_t d64_;
   233   static uint64_t DiyFpToUint64(DiyFp diy_fp) {
   234     uint64_t significand = diy_fp.f();
   235     int exponent = diy_fp.e();
   236     while (significand > kHiddenBit + kSignificandMask) {
   237       significand >>= 1;
   238       exponent++;
   239     }
   240     if (exponent >= kMaxExponent) {
   241       return kInfinity;
   242     }
   243     if (exponent < kDenormalExponent) {
   244       return 0;
   245     }
   246     while (exponent > kDenormalExponent && (significand & kHiddenBit) == 0) {
   247       significand <<= 1;
   248       exponent--;
   249     }
   250     uint64_t biased_exponent;
   251     if (exponent == kDenormalExponent && (significand & kHiddenBit) == 0) {
   252       biased_exponent = 0;
   253     } else {
   254       biased_exponent = static_cast<uint64_t>(exponent + kExponentBias);
   255     }
   256     return (significand & kSignificandMask) |
   257         (biased_exponent << kPhysicalSignificandSize);
   258   }
   259 };
   261 class Single {
   262  public:
   263   static const uint32_t kSignMask = 0x80000000;
   264   static const uint32_t kExponentMask = 0x7F800000;
   265   static const uint32_t kSignificandMask = 0x007FFFFF;
   266   static const uint32_t kHiddenBit = 0x00800000;
   267   static const int kPhysicalSignificandSize = 23;  // Excludes the hidden bit.
   268   static const int kSignificandSize = 24;
   270   Single() : d32_(0) {}
   271   explicit Single(float f) : d32_(float_to_uint32(f)) {}
   272   explicit Single(uint32_t d32) : d32_(d32) {}
   274   // The value encoded by this Single must be greater or equal to +0.0.
   275   // It must not be special (infinity, or NaN).
   276   DiyFp AsDiyFp() const {
   277     ASSERT(Sign() > 0);
   278     ASSERT(!IsSpecial());
   279     return DiyFp(Significand(), Exponent());
   280   }
   282   // Returns the single's bit as uint64.
   283   uint32_t AsUint32() const {
   284     return d32_;
   285   }
   287   int Exponent() const {
   288     if (IsDenormal()) return kDenormalExponent;
   290     uint32_t d32 = AsUint32();
   291     int biased_e =
   292         static_cast<int>((d32 & kExponentMask) >> kPhysicalSignificandSize);
   293     return biased_e - kExponentBias;
   294   }
   296   uint32_t Significand() const {
   297     uint32_t d32 = AsUint32();
   298     uint32_t significand = d32 & kSignificandMask;
   299     if (!IsDenormal()) {
   300       return significand + kHiddenBit;
   301     } else {
   302       return significand;
   303     }
   304   }
   306   // Returns true if the single is a denormal.
   307   bool IsDenormal() const {
   308     uint32_t d32 = AsUint32();
   309     return (d32 & kExponentMask) == 0;
   310   }
   312   // We consider denormals not to be special.
   313   // Hence only Infinity and NaN are special.
   314   bool IsSpecial() const {
   315     uint32_t d32 = AsUint32();
   316     return (d32 & kExponentMask) == kExponentMask;
   317   }
   319   bool IsNan() const {
   320     uint32_t d32 = AsUint32();
   321     return ((d32 & kExponentMask) == kExponentMask) &&
   322         ((d32 & kSignificandMask) != 0);
   323   }
   325   bool IsInfinite() const {
   326     uint32_t d32 = AsUint32();
   327     return ((d32 & kExponentMask) == kExponentMask) &&
   328         ((d32 & kSignificandMask) == 0);
   329   }
   331   int Sign() const {
   332     uint32_t d32 = AsUint32();
   333     return (d32 & kSignMask) == 0? 1: -1;
   334   }
   336   // Computes the two boundaries of this.
   337   // The bigger boundary (m_plus) is normalized. The lower boundary has the same
   338   // exponent as m_plus.
   339   // Precondition: the value encoded by this Single must be greater than 0.
   340   void NormalizedBoundaries(DiyFp* out_m_minus, DiyFp* out_m_plus) const {
   341     ASSERT(value() > 0.0);
   342     DiyFp v = this->AsDiyFp();
   343     DiyFp m_plus = DiyFp::Normalize(DiyFp((v.f() << 1) + 1, v.e() - 1));
   344     DiyFp m_minus;
   345     if (LowerBoundaryIsCloser()) {
   346       m_minus = DiyFp((v.f() << 2) - 1, v.e() - 2);
   347     } else {
   348       m_minus = DiyFp((v.f() << 1) - 1, v.e() - 1);
   349     }
   350     m_minus.set_f(m_minus.f() << (m_minus.e() - m_plus.e()));
   351     m_minus.set_e(m_plus.e());
   352     *out_m_plus = m_plus;
   353     *out_m_minus = m_minus;
   354   }
   356   // Precondition: the value encoded by this Single must be greater or equal
   357   // than +0.0.
   358   DiyFp UpperBoundary() const {
   359     ASSERT(Sign() > 0);
   360     return DiyFp(Significand() * 2 + 1, Exponent() - 1);
   361   }
   363   bool LowerBoundaryIsCloser() const {
   364     // The boundary is closer if the significand is of the form f == 2^p-1 then
   365     // the lower boundary is closer.
   366     // Think of v = 1000e10 and v- = 9999e9.
   367     // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but
   368     // at a distance of 1e8.
   369     // The only exception is for the smallest normal: the largest denormal is
   370     // at the same distance as its successor.
   371     // Note: denormals have the same exponent as the smallest normals.
   372     bool physical_significand_is_zero = ((AsUint32() & kSignificandMask) == 0);
   373     return physical_significand_is_zero && (Exponent() != kDenormalExponent);
   374   }
   376   float value() const { return uint32_to_float(d32_); }
   378   static float Infinity() {
   379     return Single(kInfinity).value();
   380   }
   382   static float NaN() {
   383     return Single(kNaN).value();
   384   }
   386  private:
   387   static const int kExponentBias = 0x7F + kPhysicalSignificandSize;
   388   static const int kDenormalExponent = -kExponentBias + 1;
   389   static const int kMaxExponent = 0xFF - kExponentBias;
   390   static const uint32_t kInfinity = 0x7F800000;
   391   static const uint32_t kNaN = 0x7FC00000;
   393   const uint32_t d32_;
   394 };
   396 }  // namespace double_conversion
   398 #endif  // DOUBLE_CONVERSION_DOUBLE_H_

mercurial