1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 * PR assertion checker.
14 #include "mozilla/Assertions.h"
15 #include "mozilla/Compiler.h"
16 #include "mozilla/GuardObjects.h"
20 #include "js/Utility.h"
22 #define JS_ALWAYS_TRUE(expr) MOZ_ALWAYS_TRUE(expr)
23 #define JS_ALWAYS_FALSE(expr) MOZ_ALWAYS_FALSE(expr)
26 # define JS_DIAGNOSTICS_ASSERT(expr) MOZ_ASSERT(expr)
27 #elif defined(JS_CRASH_DIAGNOSTICS)
28 # define JS_DIAGNOSTICS_ASSERT(expr) do { if (MOZ_UNLIKELY(!(expr))) MOZ_CRASH(); } while(0)
30 # define JS_DIAGNOSTICS_ASSERT(expr) ((void) 0)
33 static MOZ_ALWAYS_INLINE
void *
34 js_memcpy(void *dst_
, const void *src_
, size_t len
)
36 char *dst
= (char *) dst_
;
37 const char *src
= (const char *) src_
;
38 JS_ASSERT_IF(dst
>= src
, (size_t) (dst
- src
) >= len
);
39 JS_ASSERT_IF(src
>= dst
, (size_t) (src
- dst
) >= len
);
41 return memcpy(dst
, src
, len
);
47 struct AlignmentTestStruct
53 /* This macro determines the alignment requirements of a type. */
54 #define JS_ALIGNMENT_OF(t_) \
55 (sizeof(js::AlignmentTestStruct<t_>) - sizeof(t_))
58 class AlignedPtrAndFlag
63 AlignedPtrAndFlag(T
*t
, bool aFlag
) {
64 JS_ASSERT((uintptr_t(t
) & 1) == 0);
65 bits
= uintptr_t(t
) | uintptr_t(aFlag
);
69 return (T
*)(bits
& ~uintptr_t(1));
73 return (bits
& 1) != 0;
77 JS_ASSERT((uintptr_t(t
) & 1) == 0);
78 bits
= uintptr_t(t
) | uintptr_t(flag());
86 bits
&= ~uintptr_t(1);
89 void set(T
*t
, bool aFlag
) {
90 JS_ASSERT((uintptr_t(t
) & 1) == 0);
91 bits
= uintptr_t(t
) | aFlag
;
97 Reverse(T
*beg
, T
*end
)
111 Find(T
*beg
, T
*end
, const T
&v
)
113 for (T
*p
= beg
; p
!= end
; ++p
) {
120 template <class Container
>
121 static inline typename
Container::ElementType
*
122 Find(Container
&c
, const typename
Container::ElementType
&v
)
124 return Find(c
.begin(), c
.end(), v
);
127 template <typename InputIterT
, typename CallableT
>
129 ForEach(InputIterT begin
, InputIterT end
, CallableT f
)
131 for (; begin
!= end
; ++begin
)
139 return t1
< t2
? t1
: t2
;
146 return t1
> t2
? t1
: t2
;
149 /* Allows a const variable to be initialized after its declaration. */
152 InitConst(const T
&t
)
154 return const_cast<T
&>(t
);
157 template <class T
, class U
>
158 MOZ_ALWAYS_INLINE T
&
166 class AutoScopedAssign
169 AutoScopedAssign(T
*addr
, const T
&value
170 MOZ_GUARD_OBJECT_NOTIFIER_PARAM
)
171 : addr_(addr
), old(*addr_
)
173 MOZ_GUARD_OBJECT_NOTIFIER_INIT
;
177 ~AutoScopedAssign() { *addr_
= old
; }
180 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
185 template <typename T
>
189 return t
&& !(t
& (t
- 1));
192 template <typename T
, typename U
>
194 ComputeByteAlignment(T bytes
, U alignment
)
196 JS_ASSERT(IsPowerOfTwo(alignment
));
197 return (alignment
- (bytes
% alignment
)) % alignment
;
200 template <typename T
, typename U
>
202 AlignBytes(T bytes
, U alignment
)
204 return bytes
+ ComputeByteAlignment(bytes
, alignment
);
207 static MOZ_ALWAYS_INLINE
size_t
208 UnsignedPtrDiff(const void *bigger
, const void *smaller
)
210 return size_t(bigger
) - size_t(smaller
);
213 /*****************************************************************************/
215 /* A bit array is an array of bits represented by an array of words (size_t). */
217 static const size_t BitArrayElementBits
= sizeof(size_t) * CHAR_BIT
;
219 static inline unsigned
220 NumWordsForBitArrayOfLength(size_t length
)
222 return (length
+ (BitArrayElementBits
- 1)) / BitArrayElementBits
;
225 static inline unsigned
226 BitArrayIndexToWordIndex(size_t length
, size_t bitIndex
)
228 unsigned wordIndex
= bitIndex
/ BitArrayElementBits
;
229 JS_ASSERT(wordIndex
< length
);
234 BitArrayIndexToWordMask(size_t i
)
236 return size_t(1) << (i
% BitArrayElementBits
);
240 IsBitArrayElementSet(size_t *array
, size_t length
, size_t i
)
242 return array
[BitArrayIndexToWordIndex(length
, i
)] & BitArrayIndexToWordMask(i
);
246 IsAnyBitArrayElementSet(size_t *array
, size_t length
)
248 unsigned numWords
= NumWordsForBitArrayOfLength(length
);
249 for (unsigned i
= 0; i
< numWords
; ++i
) {
257 SetBitArrayElement(size_t *array
, size_t length
, size_t i
)
259 array
[BitArrayIndexToWordIndex(length
, i
)] |= BitArrayIndexToWordMask(i
);
263 ClearBitArrayElement(size_t *array
, size_t length
, size_t i
)
265 array
[BitArrayIndexToWordIndex(length
, i
)] &= ~BitArrayIndexToWordMask(i
);
269 ClearAllBitArrayElements(size_t *array
, size_t length
)
271 for (unsigned i
= 0; i
< length
; ++i
)
278 Poison(void *ptr
, int value
, size_t num
)
280 static bool inited
= false;
281 static bool poison
= true;
283 char *env
= getenv("JSGC_DISABLE_POISONING");
290 return memset(ptr
, value
, num
);
295 /* Crash diagnostics */
297 # define JS_CRASH_DIAGNOSTICS 1
299 #if defined(JS_CRASH_DIAGNOSTICS) || defined(JS_GC_ZEAL)
300 # define JS_POISON(p, val, size) Poison(p, val, size)
302 # define JS_POISON(p, val, size) ((void) 0)
305 /* Bug 984101: Disable labeled poisoning until we have poison checking. */
306 #define JS_EXTRA_POISON(p, val, size) ((void) 0)
310 # define JS_BASIC_STATS 1
312 #ifdef JS_BASIC_STATS
314 typedef struct JSBasicStats
{
319 uint32_t logscale
; /* logarithmic scale: 0 (linear), 2, 10 */
322 # define JS_INIT_STATIC_BASIC_STATS {0,0,0,0,0,{0,0,0,0,0,0,0,0,0,0,0}}
323 # define JS_BASIC_STATS_INIT(bs) memset((bs), 0, sizeof(JSBasicStats))
324 # define JS_BASIC_STATS_ACCUM(bs,val) \
325 JS_BasicStatsAccum(bs, val)
326 # define JS_MeanAndStdDevBS(bs,sigma) \
327 JS_MeanAndStdDev((bs)->num, (bs)->sum, (bs)->sqsum, sigma)
329 JS_BasicStatsAccum(JSBasicStats
*bs
, uint32_t val
);
331 JS_MeanAndStdDev(uint32_t num
, double sum
, double sqsum
, double *sigma
);
333 JS_DumpBasicStats(JSBasicStats
*bs
, const char *title
, FILE *fp
);
335 JS_DumpHistogram(JSBasicStats
*bs
, FILE *fp
);
337 # define JS_BASIC_STATS_ACCUM(bs,val)
340 /* A jsbitmap_t is a long integer that can be used for bitmaps. */
341 typedef size_t jsbitmap
;
342 #define JS_BITMAP_NBITS (sizeof(jsbitmap) * CHAR_BIT)
343 #define JS_TEST_BIT(_map,_bit) ((_map)[(_bit)/JS_BITMAP_NBITS] & \
344 (jsbitmap(1)<<((_bit)%JS_BITMAP_NBITS)))
345 #define JS_SET_BIT(_map,_bit) ((_map)[(_bit)/JS_BITMAP_NBITS] |= \
346 (jsbitmap(1)<<((_bit)%JS_BITMAP_NBITS)))
347 #define JS_CLEAR_BIT(_map,_bit) ((_map)[(_bit)/JS_BITMAP_NBITS] &= \
348 ~(jsbitmap(1)<<((_bit)%JS_BITMAP_NBITS)))
350 /* Wrapper for various macros to stop warnings coming from their expansions. */
351 #if defined(__clang__)
352 # define JS_SILENCE_UNUSED_VALUE_IN_EXPR(expr) \
354 _Pragma("clang diagnostic push") \
355 /* If these _Pragmas cause warnings for you, try disabling ccache. */ \
356 _Pragma("clang diagnostic ignored \"-Wunused-value\"") \
358 _Pragma("clang diagnostic pop") \
362 #if MOZ_GCC_VERSION_AT_LEAST(4, 6, 0)
363 # define JS_SILENCE_UNUSED_VALUE_IN_EXPR(expr) \
365 _Pragma("GCC diagnostic push") \
366 _Pragma("GCC diagnostic ignored \"-Wunused-but-set-variable\"") \
368 _Pragma("GCC diagnostic pop") \
373 #if !defined(JS_SILENCE_UNUSED_VALUE_IN_EXPR)
374 # define JS_SILENCE_UNUSED_VALUE_IN_EXPR(expr) \
380 #endif /* jsutil_h */