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 |