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