LCOV - app.info - js/src/jsutil.h

LCOV - code coverage report
| Current view: | directory - js/src - jsutil.h (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 59 | 58 | 98.3 %
| Date: | 2012-07-07 | Functions: | 100 | 90 | 90.0 %

           1                 : /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
           2                 :  *
           3                 :  * ***** BEGIN LICENSE BLOCK *****
           4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           5                 :  *
           6                 :  * The contents of this file are subject to the Mozilla Public License Version
           7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           8                 :  * the License. You may obtain a copy of the License at
           9                 :  * http://www.mozilla.org/MPL/
          10                 :  *
          11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          13                 :  * for the specific language governing rights and limitations under the
          14                 :  * License.
          15                 :  *
          16                 :  * The Original Code is Mozilla Communicator client code, released
          17                 :  * March 31, 1998.
          18                 :  *
          19                 :  * The Initial Developer of the Original Code is
          20                 :  * Netscape Communications Corporation.
          21                 :  * Portions created by the Initial Developer are Copyright (C) 1998
          22                 :  * the Initial Developer. All Rights Reserved.
          23                 :  *
          24                 :  * Contributor(s):
          25                 :  *
          26                 :  * Alternatively, the contents of this file may be used under the terms of
          27                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
          28                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          30                 :  * of those above. If you wish to allow use of your version of this file only
          31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          32                 :  * use your version of this file under the terms of the MPL, indicate your
          33                 :  * decision by deleting the provisions above and replace them with the notice
          34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          35                 :  * the provisions above, a recipient may use your version of this file under
          36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          37                 :  *
          38                 :  * ***** END LICENSE BLOCK ***** */
          39                 :
          40                 : /*
          41                 :  * PR assertion checker.
          42                 :  */
          43                 :
          44                 : #ifndef jsutil_h___
          45                 : #define jsutil_h___
          46                 :
          47                 : #include "mozilla/Attributes.h"
          48                 :
          49                 : #include "js/Utility.h"
          50                 :
          51                 : /* Forward declarations. */
          52                 : struct JSContext;
          53                 :
          54                 : static JS_ALWAYS_INLINE void *
          55       674790366 : js_memcpy(void *dst_, const void *src_, size_t len)
          56                 : {
          57       674790366 :     char *dst = (char *) dst_;
          58       674790366 :     const char *src = (const char *) src_;
          59       674790366 :     JS_ASSERT_IF(dst >= src, (size_t) (dst - src) >= len);
          60       674790373 :     JS_ASSERT_IF(src >= dst, (size_t) (src - dst) >= len);
          61                 :
          62       674790373 :     return memcpy(dst, src, len);
          63                 : }
          64                 :
          65                 : #ifdef __cplusplus
          66                 : namespace js {
          67                 :
          68                 : template <class T>
          69                 : class AlignedPtrAndFlag
          70                 : {
          71                 :     uintptr_t bits;
          72                 :
          73                 :   public:
          74                 :     AlignedPtrAndFlag(T *t, bool flag) {
          75                 :         JS_ASSERT((uintptr_t(t) & 1) == 0);
          76                 :         bits = uintptr_t(t) | uintptr_t(flag);
          77                 :     }
          78                 :
          79                 :     T *ptr() const {
          80                 :         return (T *)(bits & ~uintptr_t(1));
          81                 :     }
          82                 :
          83                 :     bool flag() const {
          84                 :         return (bits & 1) != 0;
          85                 :     }
          86                 :
          87                 :     void setPtr(T *t) {
          88                 :         JS_ASSERT((uintptr_t(t) & 1) == 0);
          89                 :         bits = uintptr_t(t) | uintptr_t(flag());
          90                 :     }
          91                 :
          92                 :     void setFlag() {
          93                 :         bits |= 1;
          94                 :     }
          95                 :
          96                 :     void unsetFlag() {
          97                 :         bits &= ~uintptr_t(1);
          98                 :     }
          99                 :
         100                 :     void set(T *t, bool flag) {
         101                 :         JS_ASSERT((uintptr_t(t) & 1) == 0);
         102                 :         bits = uintptr_t(t) | flag;
         103                 :     }
         104                 : };
         105                 :
         106                 : template <class T>
         107                 : static inline void
         108         3667913 : Reverse(T *beg, T *end)
         109                 : {
         110        18296499 :     while (beg != end) {
         111        11918324 :         if (--end == beg)
         112          957651 :             return;
         113        10960673 :         T tmp = *beg;
         114        10960673 :         *beg = *end;
         115        10960673 :         *end = tmp;
         116        10960673 :         ++beg;
         117                 :     }
         118                 : }
         119                 :
         120                 : template <class T>
         121                 : static inline T *
         122              99 : Find(T *beg, T *end, const T &v)
         123                 : {
         124             216 :     for (T *p = beg; p != end; ++p) {
         125             117 :         if (*p == v)
         126               0 :             return p;
         127                 :     }
         128              99 :     return end;
         129                 : }
         130                 :
         131                 : template <class Container>
         132                 : static inline typename Container::ElementType *
         133              99 : Find(Container &c, const typename Container::ElementType &v)
         134                 : {
         135              99 :     return Find(c.begin(), c.end(), v);
         136                 : }
         137                 :
         138                 : template <typename InputIterT, typename CallableT>
         139                 : void
         140                 : ForEach(InputIterT begin, InputIterT end, CallableT f)
         141                 : {
         142                 :     for (; begin != end; ++begin)
         143                 :         f(*begin);
         144                 : }
         145                 :
         146                 : template <class T>
         147                 : static inline T
         148          288753 : Min(T t1, T t2)
         149                 : {
         150          288753 :     return t1 < t2 ? t1 : t2;
         151                 : }
         152                 :
         153                 : template <class T>
         154                 : static inline T
         155       604204958 : Max(T t1, T t2)
         156                 : {
         157       604204958 :     return t1 > t2 ? t1 : t2;
         158                 : }
         159                 :
         160                 : /* Allows a const variable to be initialized after its declaration. */
         161                 : template <class T>
         162                 : static T&
         163                 : InitConst(const T &t)
         164                 : {
         165                 :     return const_cast<T &>(t);
         166                 : }
         167                 :
         168                 : template <class T, class U>
         169                 : JS_ALWAYS_INLINE T &
         170         6140432 : ImplicitCast(U &u)
         171                 : {
         172         6140432 :     T &t = u;
         173         6140432 :     return t;
         174                 : }
         175                 :
         176                 : template<typename T>
         177                 : class AutoScopedAssign
         178                 : {
         179                 :   private:
         180                 :     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
         181                 :     T *addr;
         182                 :     T old;
         183                 :
         184                 :   public:
         185                 :     AutoScopedAssign(T *addr, const T &value JS_GUARD_OBJECT_NOTIFIER_PARAM)
         186                 :         : addr(addr), old(*addr)
         187                 :     {
         188                 :         JS_GUARD_OBJECT_NOTIFIER_INIT;
         189                 :         *addr = value;
         190                 :     }
         191                 :
         192                 :     ~AutoScopedAssign() { *addr = old; }
         193                 : };
         194                 :
         195                 : template <class T>
         196                 : JS_ALWAYS_INLINE static void
         197       173876185 : PodZero(T *t)
         198                 : {
         199       173876185 :     memset(t, 0, sizeof(T));
         200       173876185 : }
         201                 :
         202                 : template <class T>
         203                 : JS_ALWAYS_INLINE static void
         204        13086873 : PodZero(T *t, size_t nelem)
         205                 : {
         206                 :     /*
         207                 :      * This function is often called with 'nelem' small; we use an
         208                 :      * inline loop instead of calling 'memset' with a non-constant
         209                 :      * length.  The compiler should inline the memset call with constant
         210                 :      * size, though.
         211                 :      */
         212       380587093 :     for (T *end = t + nelem; t != end; ++t)
         213       367500220 :         memset(t, 0, sizeof(T));
         214        13086873 : }
         215                 :
         216                 : /*
         217                 :  * Arrays implicitly convert to pointers to their first element, which is
         218                 :  * dangerous when combined with the above PodZero definitions. Adding an
         219                 :  * overload for arrays is ambiguous, so we need another identifier. The
         220                 :  * ambiguous overload is left to catch mistaken uses of PodZero; if you get a
         221                 :  * compile error involving PodZero and array types, use PodArrayZero instead.
         222                 :  */
         223                 : template <class T, size_t N> static void PodZero(T (&)[N]);          /* undefined */
         224                 : template <class T, size_t N> static void PodZero(T (&)[N], size_t);  /* undefined */
         225                 :
         226                 : template <class T, size_t N>
         227                 : JS_ALWAYS_INLINE static void
         228         1642592 : PodArrayZero(T (&t)[N])
         229                 : {
         230         1642592 :     memset(t, 0, N * sizeof(T));
         231         1642592 : }
         232                 :
         233                 : template <class T>
         234                 : JS_ALWAYS_INLINE static void
         235       636474045 : PodAssign(T *dst, const T *src)
         236                 : {
         237       636474045 :     js_memcpy((char *) dst, (const char *) src, sizeof(T));
         238       636474046 : }
         239                 :
         240                 : template <class T>
         241                 : JS_ALWAYS_INLINE static void
         242       134154597 : PodCopy(T *dst, const T *src, size_t nelem)
         243                 : {
         244                 :     /* Cannot find portable word-sized abs(). */
         245       134154597 :     JS_ASSERT_IF(dst >= src, size_t(dst - src) >= nelem);
         246       134154596 :     JS_ASSERT_IF(src >= dst, size_t(src - dst) >= nelem);
         247                 :
         248       134154596 :     if (nelem < 128) {
         249                 :         /*
         250                 :          * Avoid using operator= in this loop, as it may have been
         251                 :          * intentionally deleted by the POD type.
         252                 :          */
         253       768766057 :         for (const T *srcend = src + nelem; src != srcend; ++src, ++dst)
         254       636466536 :             PodAssign(dst, src);
         255                 :     } else {
         256         1855075 :         memcpy(dst, src, nelem * sizeof(T));
         257                 :     }
         258       134154596 : }
         259                 :
         260                 : template <class T>
         261                 : JS_ALWAYS_INLINE static bool
         262        56183220 : PodEqual(T *one, T *two, size_t len)
         263                 : {
         264        56183220 :     if (len < 128) {
         265        55998919 :         T *p1end = one + len;
         266       643986506 :         for (T *p1 = one, *p2 = two; p1 != p1end; ++p1, ++p2) {
         267       590102312 :             if (*p1 != *p2)
         268         2114725 :                 return false;
         269                 :         }
         270        53884194 :         return true;
         271                 :     }
         272                 :
         273          184301 :     return !memcmp(one, two, len * sizeof(T));
         274                 : }
         275                 :
         276                 : JS_ALWAYS_INLINE static size_t
         277             270 : UnsignedPtrDiff(const void *bigger, const void *smaller)
         278                 : {
         279             270 :     return size_t(bigger) - size_t(smaller);
         280                 : }
         281                 :
         282                 : /*
         283                 :  * Ordinarily, a function taking a JSContext* 'cx' parameter reports errors on
         284                 :  * the context. In some cases, functions optionally report and indicate this by
         285                 :  * taking a nullable 'maybecx' parameter. In some cases, though, a function
         286                 :  * always needs a 'cx', but optionally reports. This option is presented by the
         287                 :  * MaybeReportError.
         288                 :  */
         289                 : enum MaybeReportError { REPORT_ERROR = true, DONT_REPORT_ERROR = false };
         290                 :
         291                 : }  /* namespace js */
         292                 : #endif  /* __cplusplus */
         293                 :
         294                 : /*
         295                 :  * JS_ROTATE_LEFT32
         296                 :  *
         297                 :  * There is no rotate operation in the C Language so the construct (a << 4) |
         298                 :  * (a >> 28) is used instead. Most compilers convert this to a rotate
         299                 :  * instruction but some versions of MSVC don't without a little help.  To get
         300                 :  * MSVC to generate a rotate instruction, we have to use the _rotl intrinsic
         301                 :  * and use a pragma to make _rotl inline.
         302                 :  *
         303                 :  * MSVC in VS2005 will do an inline rotate instruction on the above construct.
         304                 :  */
         305                 : #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || \
         306                 :     defined(_M_X64))
         307                 : #include <stdlib.h>
         308                 : #pragma intrinsic(_rotl)
         309                 : #define JS_ROTATE_LEFT32(a, bits) _rotl(a, bits)
         310                 : #else
         311                 : #define JS_ROTATE_LEFT32(a, bits) (((a) << (bits)) | ((a) >> (32 - (bits))))
         312                 : #endif
         313                 :
         314                 : /* Static control-flow checks. */
         315                 : #ifdef NS_STATIC_CHECKING
         316                 : /* Trigger a control flow check to make sure that code flows through label */
         317                 : inline __attribute__ ((unused)) void MUST_FLOW_THROUGH(const char *label) {}
         318                 :
         319                 : /* Avoid unused goto-label warnings. */
         320                 : # define MUST_FLOW_LABEL(label) goto label; label:
         321                 :
         322                 : #else
         323                 : # define MUST_FLOW_THROUGH(label)            ((void) 0)
         324                 : # define MUST_FLOW_LABEL(label)
         325                 : #endif
         326                 :
         327                 : /* Crash diagnostics */
         328                 : #ifdef DEBUG
         329                 : # define JS_CRASH_DIAGNOSTICS 1
         330                 : #endif
         331                 : #ifdef JS_CRASH_DIAGNOSTICS
         332                 : # define JS_POISON(p, val, size) memset((p), (val), (size))
         333                 : # define JS_OPT_ASSERT(expr)                                                  \
         334                 :     ((expr) ? (void)0 : MOZ_Assert(#expr, __FILE__, __LINE__))
         335                 : # define JS_OPT_ASSERT_IF(cond, expr)                                         \
         336                 :     ((!(cond) || (expr)) ? (void)0 : MOZ_Assert(#expr, __FILE__, __LINE__))
         337                 : #else
         338                 : # define JS_POISON(p, val, size) ((void) 0)
         339                 : # define JS_OPT_ASSERT(expr) ((void) 0)
         340                 : # define JS_OPT_ASSERT_IF(cond, expr) ((void) 0)
         341                 : #endif
         342                 :
         343                 : /* Basic stats */
         344                 : #ifdef DEBUG
         345                 : # define JS_BASIC_STATS 1
         346                 : #endif
         347                 : #ifdef JS_BASIC_STATS
         348                 : # include <stdio.h>
         349                 : typedef struct JSBasicStats {
         350                 :     uint32_t    num;
         351                 :     uint32_t    max;
         352                 :     double      sum;
         353                 :     double      sqsum;
         354                 :     uint32_t    logscale;           /* logarithmic scale: 0 (linear), 2, 10 */
         355                 :     uint32_t    hist[11];
         356                 : } JSBasicStats;
         357                 : # define JS_INIT_STATIC_BASIC_STATS  {0,0,0,0,0,{0,0,0,0,0,0,0,0,0,0,0}}
         358                 : # define JS_BASIC_STATS_INIT(bs)     memset((bs), 0, sizeof(JSBasicStats))
         359                 : # define JS_BASIC_STATS_ACCUM(bs,val)                                         \
         360                 :     JS_BasicStatsAccum(bs, val)
         361                 : # define JS_MeanAndStdDevBS(bs,sigma)                                         \
         362                 :     JS_MeanAndStdDev((bs)->num, (bs)->sum, (bs)->sqsum, sigma)
         363                 : extern void
         364                 : JS_BasicStatsAccum(JSBasicStats *bs, uint32_t val);
         365                 : extern double
         366                 : JS_MeanAndStdDev(uint32_t num, double sum, double sqsum, double *sigma);
         367                 : extern void
         368                 : JS_DumpBasicStats(JSBasicStats *bs, const char *title, FILE *fp);
         369                 : extern void
         370                 : JS_DumpHistogram(JSBasicStats *bs, FILE *fp);
         371                 : #else
         372                 : # define JS_BASIC_STATS_ACCUM(bs,val)
         373                 : #endif
         374                 :
         375                 : /* A jsbitmap_t is a long integer that can be used for bitmaps. */
         376                 : typedef size_t jsbitmap;
         377                 : #define JS_TEST_BIT(_map,_bit)  ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] &      \
         378                 :                                  ((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1))))
         379                 : #define JS_SET_BIT(_map,_bit)   ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] |=     \
         380                 :                                  ((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1))))
         381                 : #define JS_CLEAR_BIT(_map,_bit) ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] &=     \
         382                 :                                  ~((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1))))
         383                 :
         384                 : /* Wrapper for various macros to stop warnings coming from their expansions. */
         385                 : #if defined(__clang__)
         386                 : # define JS_SILENCE_UNUSED_VALUE_IN_EXPR(expr)                                \
         387                 :     JS_BEGIN_MACRO                                                            \
         388                 :         _Pragma("clang diagnostic push")                                      \
         389                 :         _Pragma("clang diagnostic ignored \"-Wunused-value\"")                \
         390                 :         expr;                                                                 \
         391                 :         _Pragma("clang diagnostic pop")                                       \
         392                 :     JS_END_MACRO
         393                 : #elif (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
         394                 : # define JS_SILENCE_UNUSED_VALUE_IN_EXPR(expr)                                \
         395                 :     JS_BEGIN_MACRO                                                            \
         396                 :         _Pragma("GCC diagnostic push")                                        \
         397                 :         _Pragma("GCC diagnostic ignored \"-Wunused-but-set-variable\"")       \
         398                 :         expr;                                                                 \
         399                 :         _Pragma("GCC diagnostic pop")                                         \
         400                 :     JS_END_MACRO
         401                 : #else
         402                 : # define JS_SILENCE_UNUSED_VALUE_IN_EXPR(expr)                                \
         403                 :     JS_BEGIN_MACRO                                                            \
         404                 :         expr;                                                                 \
         405                 :     JS_END_MACRO
         406                 : #endif
         407                 :
         408                 : #endif /* jsutil_h___ */

Generated by: LCOV version 1.7