Home | History | Annotate | Download | only in src
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_CHECKS_H_
      6 #define V8_CHECKS_H_
      7 
      8 #include <string.h>
      9 
     10 #include "include/v8stdint.h"
     11 #include "src/base/build_config.h"
     12 
     13 extern "C" void V8_Fatal(const char* file, int line, const char* format, ...);
     14 
     15 
     16 // The FATAL, UNREACHABLE and UNIMPLEMENTED macros are useful during
     17 // development, but they should not be relied on in the final product.
     18 #ifdef DEBUG
     19 #define FATAL(msg)                              \
     20   V8_Fatal(__FILE__, __LINE__, "%s", (msg))
     21 #define UNIMPLEMENTED()                         \
     22   V8_Fatal(__FILE__, __LINE__, "unimplemented code")
     23 #define UNREACHABLE()                           \
     24   V8_Fatal(__FILE__, __LINE__, "unreachable code")
     25 #else
     26 #define FATAL(msg)                              \
     27   V8_Fatal("", 0, "%s", (msg))
     28 #define UNIMPLEMENTED()                         \
     29   V8_Fatal("", 0, "unimplemented code")
     30 #define UNREACHABLE() ((void) 0)
     31 #endif
     32 
     33 // Simulator specific helpers.
     34 // We can't use USE_SIMULATOR here because it isn't defined yet.
     35 #if V8_TARGET_ARCH_ARM64 && !V8_HOST_ARCH_ARM64
     36   // TODO(all): If possible automatically prepend an indicator like
     37   // UNIMPLEMENTED or LOCATION.
     38   #define ASM_UNIMPLEMENTED(message)                                         \
     39   __ Debug(message, __LINE__, NO_PARAM)
     40   #define ASM_UNIMPLEMENTED_BREAK(message)                                   \
     41   __ Debug(message, __LINE__,                                                \
     42            FLAG_ignore_asm_unimplemented_break ? NO_PARAM : BREAK)
     43   #define ASM_LOCATION(message)                                              \
     44   __ Debug("LOCATION: " message, __LINE__, NO_PARAM)
     45 #else
     46   #define ASM_UNIMPLEMENTED(message)
     47   #define ASM_UNIMPLEMENTED_BREAK(message)
     48   #define ASM_LOCATION(message)
     49 #endif
     50 
     51 
     52 // The CHECK macro checks that the given condition is true; if not, it
     53 // prints a message to stderr and aborts.
     54 #define CHECK(condition) do {                                       \
     55     if (!(condition)) {                                             \
     56       V8_Fatal(__FILE__, __LINE__, "CHECK(%s) failed", #condition); \
     57     }                                                               \
     58   } while (0)
     59 
     60 
     61 // Helper function used by the CHECK_EQ function when given int
     62 // arguments.  Should not be called directly.
     63 inline void CheckEqualsHelper(const char* file, int line,
     64                               const char* expected_source, int expected,
     65                               const char* value_source, int value) {
     66   if (expected != value) {
     67     V8_Fatal(file, line,
     68              "CHECK_EQ(%s, %s) failed\n#   Expected: %i\n#   Found: %i",
     69              expected_source, value_source, expected, value);
     70   }
     71 }
     72 
     73 
     74 // Helper function used by the CHECK_EQ function when given int64_t
     75 // arguments.  Should not be called directly.
     76 inline void CheckEqualsHelper(const char* file, int line,
     77                               const char* expected_source,
     78                               int64_t expected,
     79                               const char* value_source,
     80                               int64_t value) {
     81   if (expected != value) {
     82     // Print int64_t values in hex, as two int32s,
     83     // to avoid platform-dependencies.
     84     V8_Fatal(file, line,
     85              "CHECK_EQ(%s, %s) failed\n#"
     86              "   Expected: 0x%08x%08x\n#   Found: 0x%08x%08x",
     87              expected_source, value_source,
     88              static_cast<uint32_t>(expected >> 32),
     89              static_cast<uint32_t>(expected),
     90              static_cast<uint32_t>(value >> 32),
     91              static_cast<uint32_t>(value));
     92   }
     93 }
     94 
     95 
     96 // Helper function used by the CHECK_NE function when given int
     97 // arguments.  Should not be called directly.
     98 inline void CheckNonEqualsHelper(const char* file,
     99                                  int line,
    100                                  const char* unexpected_source,
    101                                  int unexpected,
    102                                  const char* value_source,
    103                                  int value) {
    104   if (unexpected == value) {
    105     V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n#   Value: %i",
    106              unexpected_source, value_source, value);
    107   }
    108 }
    109 
    110 
    111 // Helper function used by the CHECK function when given string
    112 // arguments.  Should not be called directly.
    113 inline void CheckEqualsHelper(const char* file,
    114                               int line,
    115                               const char* expected_source,
    116                               const char* expected,
    117                               const char* value_source,
    118                               const char* value) {
    119   if ((expected == NULL && value != NULL) ||
    120       (expected != NULL && value == NULL) ||
    121       (expected != NULL && value != NULL && strcmp(expected, value) != 0)) {
    122     V8_Fatal(file, line,
    123              "CHECK_EQ(%s, %s) failed\n#   Expected: %s\n#   Found: %s",
    124              expected_source, value_source, expected, value);
    125   }
    126 }
    127 
    128 
    129 inline void CheckNonEqualsHelper(const char* file,
    130                                  int line,
    131                                  const char* expected_source,
    132                                  const char* expected,
    133                                  const char* value_source,
    134                                  const char* value) {
    135   if (expected == value ||
    136       (expected != NULL && value != NULL && strcmp(expected, value) == 0)) {
    137     V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n#   Value: %s",
    138              expected_source, value_source, value);
    139   }
    140 }
    141 
    142 
    143 // Helper function used by the CHECK function when given pointer
    144 // arguments.  Should not be called directly.
    145 inline void CheckEqualsHelper(const char* file,
    146                               int line,
    147                               const char* expected_source,
    148                               const void* expected,
    149                               const char* value_source,
    150                               const void* value) {
    151   if (expected != value) {
    152     V8_Fatal(file, line,
    153              "CHECK_EQ(%s, %s) failed\n#   Expected: %p\n#   Found: %p",
    154              expected_source, value_source,
    155              expected, value);
    156   }
    157 }
    158 
    159 
    160 inline void CheckNonEqualsHelper(const char* file,
    161                                  int line,
    162                                  const char* expected_source,
    163                                  const void* expected,
    164                                  const char* value_source,
    165                                  const void* value) {
    166   if (expected == value) {
    167     V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n#   Value: %p",
    168              expected_source, value_source, value);
    169   }
    170 }
    171 
    172 
    173 // Helper function used by the CHECK function when given floating
    174 // point arguments.  Should not be called directly.
    175 inline void CheckEqualsHelper(const char* file,
    176                               int line,
    177                               const char* expected_source,
    178                               double expected,
    179                               const char* value_source,
    180                               double value) {
    181   // Force values to 64 bit memory to truncate 80 bit precision on IA32.
    182   volatile double* exp = new double[1];
    183   *exp = expected;
    184   volatile double* val = new double[1];
    185   *val = value;
    186   if (*exp != *val) {
    187     V8_Fatal(file, line,
    188              "CHECK_EQ(%s, %s) failed\n#   Expected: %f\n#   Found: %f",
    189              expected_source, value_source, *exp, *val);
    190   }
    191   delete[] exp;
    192   delete[] val;
    193 }
    194 
    195 
    196 inline void CheckNonEqualsHelper(const char* file,
    197                               int line,
    198                               const char* expected_source,
    199                               int64_t expected,
    200                               const char* value_source,
    201                               int64_t value) {
    202   if (expected == value) {
    203     V8_Fatal(file, line,
    204              "CHECK_EQ(%s, %s) failed\n#   Expected: %f\n#   Found: %f",
    205              expected_source, value_source, expected, value);
    206   }
    207 }
    208 
    209 
    210 inline void CheckNonEqualsHelper(const char* file,
    211                                  int line,
    212                                  const char* expected_source,
    213                                  double expected,
    214                                  const char* value_source,
    215                                  double value) {
    216   // Force values to 64 bit memory to truncate 80 bit precision on IA32.
    217   volatile double* exp = new double[1];
    218   *exp = expected;
    219   volatile double* val = new double[1];
    220   *val = value;
    221   if (*exp == *val) {
    222     V8_Fatal(file, line,
    223              "CHECK_NE(%s, %s) failed\n#   Value: %f",
    224              expected_source, value_source, *val);
    225   }
    226   delete[] exp;
    227   delete[] val;
    228 }
    229 
    230 
    231 #define CHECK_EQ(expected, value) CheckEqualsHelper(__FILE__, __LINE__, \
    232   #expected, expected, #value, value)
    233 
    234 
    235 #define CHECK_NE(unexpected, value) CheckNonEqualsHelper(__FILE__, __LINE__, \
    236   #unexpected, unexpected, #value, value)
    237 
    238 
    239 #define CHECK_GT(a, b) CHECK((a) > (b))
    240 #define CHECK_GE(a, b) CHECK((a) >= (b))
    241 #define CHECK_LT(a, b) CHECK((a) < (b))
    242 #define CHECK_LE(a, b) CHECK((a) <= (b))
    243 
    244 
    245 #ifdef DEBUG
    246 #ifndef OPTIMIZED_DEBUG
    247 #define ENABLE_SLOW_ASSERTS    1
    248 #endif
    249 #endif
    250 
    251 namespace v8 {
    252 namespace internal {
    253 #ifdef ENABLE_SLOW_ASSERTS
    254 #define SLOW_ASSERT(condition) \
    255   CHECK(!v8::internal::FLAG_enable_slow_asserts || (condition))
    256 extern bool FLAG_enable_slow_asserts;
    257 #else
    258 #define SLOW_ASSERT(condition) ((void) 0)
    259 const bool FLAG_enable_slow_asserts = false;
    260 #endif
    261 
    262 // Exposed for making debugging easier (to see where your function is being
    263 // called, just add a call to DumpBacktrace).
    264 void DumpBacktrace();
    265 
    266 } }  // namespace v8::internal
    267 
    268 
    269 // The ASSERT macro is equivalent to CHECK except that it only
    270 // generates code in debug builds.
    271 #ifdef DEBUG
    272 #define ASSERT_RESULT(expr)    CHECK(expr)
    273 #define ASSERT(condition)      CHECK(condition)
    274 #define ASSERT_EQ(v1, v2)      CHECK_EQ(v1, v2)
    275 #define ASSERT_NE(v1, v2)      CHECK_NE(v1, v2)
    276 #define ASSERT_GE(v1, v2)      CHECK_GE(v1, v2)
    277 #define ASSERT_LT(v1, v2)      CHECK_LT(v1, v2)
    278 #define ASSERT_LE(v1, v2)      CHECK_LE(v1, v2)
    279 #else
    280 #define ASSERT_RESULT(expr)    (expr)
    281 #define ASSERT(condition)      ((void) 0)
    282 #define ASSERT_EQ(v1, v2)      ((void) 0)
    283 #define ASSERT_NE(v1, v2)      ((void) 0)
    284 #define ASSERT_GE(v1, v2)      ((void) 0)
    285 #define ASSERT_LT(v1, v2)      ((void) 0)
    286 #define ASSERT_LE(v1, v2)      ((void) 0)
    287 #endif
    288 
    289 #define ASSERT_NOT_NULL(p)  ASSERT_NE(NULL, p)
    290 
    291 // "Extra checks" are lightweight checks that are enabled in some release
    292 // builds.
    293 #ifdef ENABLE_EXTRA_CHECKS
    294 #define EXTRA_CHECK(condition) CHECK(condition)
    295 #else
    296 #define EXTRA_CHECK(condition) ((void) 0)
    297 #endif
    298 
    299 #endif  // V8_CHECKS_H_
    300