author | Bas Schouten <bschouten@mozilla.com> |
Thu, 12 Apr 2012 02:03:07 +0200 | |
changeset 91485 | 20218c1c79e0337a954adc6c68496e4f7d45c30d |
parent 91484 | d9964e231f469686a109f1da0a30a107c79e2ace |
child 91486 | a964ce19e78f0e29b7782127d7f515f2721889eb |
push id | 22445 |
push user | eakhgari@mozilla.com |
push date | Thu, 12 Apr 2012 16:19:55 +0000 |
treeherder | mozilla-central@901dfde60183 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | waldo |
bugs | 719776 |
milestone | 14.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
|
--- a/js/public/Utility.h +++ b/js/public/Utility.h @@ -327,32 +327,16 @@ unsigned char _BitScanReverse64(unsigned (_log2) += 4, (j_) >>= 4; \ if ((j_) >> 2) \ (_log2) += 2, (j_) >>= 2; \ if ((j_) >> 1) \ (_log2) += 1; \ JS_END_MACRO #endif -/* - * Internal function. - * Compute the log of the least power of 2 greater than or equal to n. This is - * a version of JS_CeilingLog2 that operates on unsigned integers with - * CPU-dependant size. - */ -#define JS_CEILING_LOG2W(n) ((n) <= 1 ? 0 : 1 + JS_FLOOR_LOG2W((n) - 1)) - -/* - * Internal function. - * Compute the log of the greatest power of 2 less than or equal to n. - * This is a version of JS_FloorLog2 that operates on unsigned integers with - * CPU-dependant size and requires that n != 0. - */ -#define JS_FLOOR_LOG2W(n) (JS_ASSERT((n) != 0), js_FloorLog2wImpl(n)) - #if JS_BYTES_PER_WORD == 4 # ifdef JS_HAS_BUILTIN_BITSCAN32 # define js_FloorLog2wImpl(n) \ ((size_t)(JS_BITS_PER_WORD - 1 - js_bitscan_clz32(n))) # else JS_PUBLIC_API(size_t) js_FloorLog2wImpl(size_t n); # endif #elif JS_BYTES_PER_WORD == 8 @@ -361,16 +345,37 @@ JS_PUBLIC_API(size_t) js_FloorLog2wImpl( ((size_t)(JS_BITS_PER_WORD - 1 - js_bitscan_clz64(n))) # else JS_PUBLIC_API(size_t) js_FloorLog2wImpl(size_t n); # endif #else # error "NOT SUPPORTED" #endif +/* + * Internal function. + * Compute the log of the least power of 2 greater than or equal to n. This is + * a version of JS_CeilingLog2 that operates on unsigned integers with + * CPU-dependant size. + */ +#define JS_CEILING_LOG2W(n) ((n) <= 1 ? 0 : 1 + JS_FLOOR_LOG2W((n) - 1)) + +/* + * Internal function. + * Compute the log of the greatest power of 2 less than or equal to n. + * This is a version of JS_FloorLog2 that operates on unsigned integers with + * CPU-dependant size and requires that n != 0. + */ +static MOZ_ALWAYS_INLINE size_t +JS_FLOOR_LOG2W(size_t n) +{ + JS_ASSERT(n != 0); + return js_FloorLog2wImpl(n); +} + JS_END_EXTERN_C #ifdef __cplusplus #include <new> /* * User guide to memory management within SpiderMonkey: *
--- a/js/src/assembler/wtf/Assertions.h +++ b/js/src/assembler/wtf/Assertions.h @@ -33,19 +33,22 @@ /* * Prevent unused-variable warnings by defining the macro WTF uses to test * for assertions taking effect. */ # define ASSERT_DISABLED 1 #endif #define ASSERT(assertion) MOZ_ASSERT(assertion) -#define ASSERT_UNUSED(variable, assertion) (((void)variable), ASSERT(assertion)) +#define ASSERT_UNUSED(variable, assertion) do { \ + (void)variable; \ + ASSERT(assertion); \ +} while (0) #define ASSERT_NOT_REACHED() MOZ_NOT_REACHED("") -#define CRASH() MOZ_Crash() +#define CRASH() MOZ_CRASH() #define COMPILE_ASSERT(exp, name) MOZ_STATIC_ASSERT(exp, #name) #endif #if 0 /* no namespaces because this file has to be includable from C and Objective-C
--- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -1531,40 +1531,43 @@ extern JSErrorFormatString js_ErrorForma #ifdef JS_THREADSAFE # define JS_ASSERT_REQUEST_DEPTH(cx) JS_ASSERT((cx)->runtime->requestDepth >= 1) #else # define JS_ASSERT_REQUEST_DEPTH(cx) ((void) 0) #endif /* - * If the operation callback flag was set, call the operation callback. - * This macro can run the full GC. Return true if it is OK to continue and - * false otherwise. - */ -#define JS_CHECK_OPERATION_LIMIT(cx) \ - (JS_ASSERT_REQUEST_DEPTH(cx), \ - (!cx->runtime->interrupt || js_InvokeOperationCallback(cx))) - -/* * Invoke the operation callback and return false if the current execution * is to be terminated. */ extern JSBool js_InvokeOperationCallback(JSContext *cx); extern JSBool js_HandleExecutionInterrupt(JSContext *cx); extern jsbytecode* js_GetCurrentBytecodePC(JSContext* cx); extern JSScript * js_GetCurrentScript(JSContext* cx); +/* + * If the operation callback flag was set, call the operation callback. + * This macro can run the full GC. Return true if it is OK to continue and + * false otherwise. + */ +static MOZ_ALWAYS_INLINE bool +JS_CHECK_OPERATION_LIMIT(JSContext *cx) +{ + JS_ASSERT_REQUEST_DEPTH(cx); + return !cx->runtime->interrupt || js_InvokeOperationCallback(cx); +} + namespace js { #ifdef JS_METHODJIT namespace mjit { void ExpandInlineFrames(JSCompartment *compartment); } #endif
--- a/mfbt/Assertions.h +++ b/mfbt/Assertions.h @@ -1,9 +1,9 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * vim: set ts=8 sw=4 et tw=99 ft=cpp: * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at: @@ -41,16 +41,25 @@ /* Implementations of runtime and static assertion macros for C and C++. */ #ifndef mozilla_Assertions_h_ #define mozilla_Assertions_h_ #include "mozilla/Attributes.h" #include "mozilla/Types.h" +#include <stdio.h> +#include <stdlib.h> +#ifndef WIN32 +# include <signal.h> +#endif +#ifdef ANDROID +# include <android/log.h> +#endif + /* * MOZ_STATIC_ASSERT may be used to assert a condition *at compile time*. This * can be useful when you make certain assumptions about what must hold for * optimal, or even correct, behavior. For example, you might assert that the * size of a struct is a multiple of the target architecture's word size: * * struct S { ... }; * MOZ_STATIC_ASSERT(sizeof(S) % sizeof(size_t) == 0, @@ -126,22 +135,78 @@ #endif #define MOZ_STATIC_ASSERT_IF(cond, expr, reason) MOZ_STATIC_ASSERT(!(cond) || (expr), reason) #ifdef __cplusplus extern "C" { #endif -extern MFBT_API(void) -MOZ_Crash(void); +#if defined(WIN32) + /* + * We used to call DebugBreak() on Windows, but amazingly, it causes + * the MSVS 2010 debugger not to be able to recover a call stack. + */ +# define MOZ_CRASH() \ + do { \ + *((volatile int *) NULL) = 123; \ + exit(3); \ + } while (0) +#elif defined(ANDROID) + /* + * On Android, raise(SIGABRT) is handled asynchronously. Seg fault now + * so we crash immediately and capture the current call stack. We need + * to specifically use the global namespace in the C++ case. + */ +# ifdef __cplusplus +# define MOZ_CRASH() \ + do { \ + *((volatile int *) NULL) = 123; \ + ::abort(); \ + } while (0) +# else +# define MOZ_CRASH() \ + do { \ + *((volatile int *) NULL) = 123; \ + abort(); \ + } while (0) +# endif +#elif defined(__APPLE__) + /* + * On Mac OS X, Breakpad ignores signals. Only real Mach exceptions are + * trapped. + */ +# define MOZ_CRASH() \ + do { \ + *((volatile int *) NULL) = 123; \ + raise(SIGABRT); /* In case above statement gets nixed by the optimizer. */ \ + } while (0) +#else +# define MOZ_CRASH() \ + do { \ + raise(SIGABRT); /* To continue from here in GDB: "signal 0". */ \ + } while (0) +#endif + extern MFBT_API(void) MOZ_Assert(const char* s, const char* file, int ln); +static MOZ_ALWAYS_INLINE void +MOZ_OutputAssertMessage(const char* s, const char *file, int ln) +{ +#ifdef ANDROID + __android_log_print(ANDROID_LOG_FATAL, "MOZ_Assert", + "Assertion failure: %s, at %s:%d\n", s, file, ln); +#else + fprintf(stderr, "Assertion failure: %s, at %s:%d\n", s, file, ln); + fflush(stderr); +#endif +} + #ifdef __cplusplus } /* extern "C" */ #endif /* * MOZ_ASSERT(expr [, explanation-string]) asserts that |expr| must be truthy in * debug builds. If it is, execution continues. Otherwise, an error message * including the expression and the explanation-string (if provided) is printed, @@ -171,20 +236,30 @@ MOZ_Assert(const char* s, const char* fi * "we already set [[PrimitiveThis]] for this String object"); * * MOZ_ASSERT has no effect in non-debug builds. It is designed to catch bugs * *only* during debugging, not "in the field". */ #ifdef DEBUG /* First the single-argument form. */ # define MOZ_ASSERT_HELPER1(expr) \ - ((expr) ? ((void)0) : MOZ_Assert(#expr, __FILE__, __LINE__)) + do { \ + if (!(expr)) { \ + MOZ_OutputAssertMessage(#expr, __FILE__, __LINE__); \ + MOZ_CRASH(); \ + } \ + } while (0) /* Now the two-argument form. */ # define MOZ_ASSERT_HELPER2(expr, explain) \ - ((expr) ? ((void)0) : MOZ_Assert(#expr " (" explain ")", __FILE__, __LINE__)) + do { \ + if (!(expr)) { \ + MOZ_OutputAssertMessage(#expr " (" explain ")", __FILE__, __LINE__); \ + MOZ_CRASH(); \ + } \ + } while (0) /* And now, helper macrology up the wazoo. */ /* * Count the number of arguments passed to MOZ_ASSERT, very carefully * tiptoeing around an MSVC bug where it improperly expands __VA_ARGS__ as a * single token in argument lists. See these URLs for details: * * http://connect.microsoft.com/VisualStudio/feedback/details/380090/variadic-macro-replacement * http://cplusplus.co.il/2010/07/17/variadic-macro-to-count-number-of-arguments/#comment-644 @@ -200,32 +275,36 @@ MOZ_Assert(const char* s, const char* fi # define MOZ_ASSERT_CHOOSE_HELPER1(count) MOZ_ASSERT_CHOOSE_HELPER2(count) # define MOZ_ASSERT_CHOOSE_HELPER(count) MOZ_ASSERT_CHOOSE_HELPER1(count) /* The actual macro. */ # define MOZ_ASSERT_GLUE(x, y) x y # define MOZ_ASSERT(...) \ MOZ_ASSERT_GLUE(MOZ_ASSERT_CHOOSE_HELPER(MOZ_COUNT_ASSERT_ARGS(__VA_ARGS__)), \ (__VA_ARGS__)) #else -# define MOZ_ASSERT(...) ((void)0) +# define MOZ_ASSERT(...) do { } while(0) #endif /* DEBUG */ /* * MOZ_ASSERT_IF(cond1, cond2) is equivalent to MOZ_ASSERT(cond2) if cond1 is * true. * * MOZ_ASSERT_IF(isPrime(num), num == 2 || isOdd(num)); * * As with MOZ_ASSERT, MOZ_ASSERT_IF has effect only in debug builds. It is * designed to catch bugs during debugging, not "in the field". */ #ifdef DEBUG -# define MOZ_ASSERT_IF(cond, expr) ((cond) ? MOZ_ASSERT(expr) : ((void)0)) +# define MOZ_ASSERT_IF(cond, expr) \ + do { \ + if (cond) \ + MOZ_ASSERT(expr); \ + } while (0) #else -# define MOZ_ASSERT_IF(cond, expr) ((void)0) +# define MOZ_ASSERT_IF(cond, expr) do { } while (0) #endif /* MOZ_NOT_REACHED_MARKER() expands (in compilers which support it) to an * expression which states that it is undefined behavior for the compiler to * reach this point. Most code should probably use the higher level * MOZ_NOT_REACHED (which expands to this when appropriate). */ #if defined(__clang__)