| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_CHECKS_H_ | 5 #ifndef V8_CHECKS_H_ |
| 6 #define V8_CHECKS_H_ | 6 #define V8_CHECKS_H_ |
| 7 | 7 |
| 8 #include <string.h> | 8 #include "src/base/logging.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 | 9 |
| 33 // Simulator specific helpers. | 10 // Simulator specific helpers. |
| 34 // We can't use USE_SIMULATOR here because it isn't defined yet. | 11 // We can't use USE_SIMULATOR here because it isn't defined yet. |
| 35 #if V8_TARGET_ARCH_ARM64 && !V8_HOST_ARCH_ARM64 | 12 #if V8_TARGET_ARCH_ARM64 && !V8_HOST_ARCH_ARM64 |
| 36 // TODO(all): If possible automatically prepend an indicator like | 13 // TODO(all): If possible automatically prepend an indicator like |
| 37 // UNIMPLEMENTED or LOCATION. | 14 // UNIMPLEMENTED or LOCATION. |
| 38 #define ASM_UNIMPLEMENTED(message) \ | 15 #define ASM_UNIMPLEMENTED(message) \ |
| 39 __ Debug(message, __LINE__, NO_PARAM) | 16 __ Debug(message, __LINE__, NO_PARAM) |
| 40 #define ASM_UNIMPLEMENTED_BREAK(message) \ | 17 #define ASM_UNIMPLEMENTED_BREAK(message) \ |
| 41 __ Debug(message, __LINE__, \ | 18 __ Debug(message, __LINE__, \ |
| 42 FLAG_ignore_asm_unimplemented_break ? NO_PARAM : BREAK) | 19 FLAG_ignore_asm_unimplemented_break ? NO_PARAM : BREAK) |
| 43 #define ASM_LOCATION(message) \ | 20 #define ASM_LOCATION(message) \ |
| 44 __ Debug("LOCATION: " message, __LINE__, NO_PARAM) | 21 __ Debug("LOCATION: " message, __LINE__, NO_PARAM) |
| 45 #else | 22 #else |
| 46 #define ASM_UNIMPLEMENTED(message) | 23 #define ASM_UNIMPLEMENTED(message) |
| 47 #define ASM_UNIMPLEMENTED_BREAK(message) | 24 #define ASM_UNIMPLEMENTED_BREAK(message) |
| 48 #define ASM_LOCATION(message) | 25 #define ASM_LOCATION(message) |
| 49 #endif | 26 #endif |
| 50 | 27 |
| 51 | 28 |
| 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 | 29 #ifdef DEBUG |
| 246 #ifndef OPTIMIZED_DEBUG | 30 #ifndef OPTIMIZED_DEBUG |
| 247 #define ENABLE_SLOW_ASSERTS 1 | 31 #define ENABLE_SLOW_ASSERTS 1 |
| 248 #endif | 32 #endif |
| 249 #endif | 33 #endif |
| 250 | 34 |
| 251 namespace v8 { | 35 namespace v8 { |
| 36 |
| 37 class Value; |
| 38 template <class T> class Handle; |
| 39 |
| 252 namespace internal { | 40 namespace internal { |
| 41 |
| 42 intptr_t HeapObjectTagMask(); |
| 43 |
| 253 #ifdef ENABLE_SLOW_ASSERTS | 44 #ifdef ENABLE_SLOW_ASSERTS |
| 254 #define SLOW_ASSERT(condition) \ | 45 #define SLOW_ASSERT(condition) \ |
| 255 CHECK(!v8::internal::FLAG_enable_slow_asserts || (condition)) | 46 CHECK(!v8::internal::FLAG_enable_slow_asserts || (condition)) |
| 256 extern bool FLAG_enable_slow_asserts; | 47 extern bool FLAG_enable_slow_asserts; |
| 257 #else | 48 #else |
| 258 #define SLOW_ASSERT(condition) ((void) 0) | 49 #define SLOW_ASSERT(condition) ((void) 0) |
| 259 const bool FLAG_enable_slow_asserts = false; | 50 const bool FLAG_enable_slow_asserts = false; |
| 260 #endif | 51 #endif |
| 261 | 52 |
| 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 | 53 } } // namespace v8::internal |
| 267 | 54 |
| 268 | 55 |
| 269 // The ASSERT macro is equivalent to CHECK except that it only | 56 void CheckNonEqualsHelper(const char* file, |
| 270 // generates code in debug builds. | 57 int line, |
| 271 #ifdef DEBUG | 58 const char* unexpected_source, |
| 272 #define ASSERT_RESULT(expr) CHECK(expr) | 59 v8::Handle<v8::Value> unexpected, |
| 273 #define ASSERT(condition) CHECK(condition) | 60 const char* value_source, |
| 274 #define ASSERT_EQ(v1, v2) CHECK_EQ(v1, v2) | 61 v8::Handle<v8::Value> value); |
| 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 | 62 |
| 289 #define ASSERT_NOT_NULL(p) ASSERT_NE(NULL, p) | 63 void CheckEqualsHelper(const char* file, |
| 64 int line, |
| 65 const char* expected_source, |
| 66 v8::Handle<v8::Value> expected, |
| 67 const char* value_source, |
| 68 v8::Handle<v8::Value> value); |
| 290 | 69 |
| 291 // "Extra checks" are lightweight checks that are enabled in some release | 70 #define ASSERT_TAG_ALIGNED(address) \ |
| 292 // builds. | 71 ASSERT((reinterpret_cast<intptr_t>(address) & HeapObjectTagMask()) == 0) |
| 293 #ifdef ENABLE_EXTRA_CHECKS | 72 |
| 294 #define EXTRA_CHECK(condition) CHECK(condition) | 73 #define ASSERT_SIZE_TAG_ALIGNED(size) ASSERT((size & HeapObjectTagMask()) == 0) |
| 295 #else | |
| 296 #define EXTRA_CHECK(condition) ((void) 0) | |
| 297 #endif | |
| 298 | 74 |
| 299 #endif // V8_CHECKS_H_ | 75 #endif // V8_CHECKS_H_ |
| OLD | NEW |