blob: e4e3f49bfaffa645d575a000e396ca5fd586e871 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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_BASE_LOGGING_H_
6#define V8_BASE_LOGGING_H_
7
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008#include <cstring>
9#include <sstream>
10#include <string>
Ben Murdochb8a8cc12014-11-26 15:28:44 +000011
Ben Murdochb8a8cc12014-11-26 15:28:44 +000012#include "src/base/build_config.h"
13
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000014extern "C" V8_NORETURN void V8_Fatal(const char* file, int line,
15 const char* format, ...);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000016
17
18// The FATAL, UNREACHABLE and UNIMPLEMENTED macros are useful during
19// development, but they should not be relied on in the final product.
20#ifdef DEBUG
21#define FATAL(msg) \
22 V8_Fatal(__FILE__, __LINE__, "%s", (msg))
23#define UNIMPLEMENTED() \
24 V8_Fatal(__FILE__, __LINE__, "unimplemented code")
25#define UNREACHABLE() \
26 V8_Fatal(__FILE__, __LINE__, "unreachable code")
27#else
28#define FATAL(msg) \
29 V8_Fatal("", 0, "%s", (msg))
30#define UNIMPLEMENTED() \
31 V8_Fatal("", 0, "unimplemented code")
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000032#define UNREACHABLE() V8_Fatal("", 0, "unreachable code")
Ben Murdochb8a8cc12014-11-26 15:28:44 +000033#endif
34
35
Ben Murdochb8a8cc12014-11-26 15:28:44 +000036namespace v8 {
37namespace base {
38
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000039// CHECK dies with a fatal error if condition is not true. It is *not*
40// controlled by DEBUG, so the check will be executed regardless of
41// compilation mode.
42//
43// We make sure CHECK et al. always evaluates their arguments, as
44// doing CHECK(FunctionWithSideEffect()) is a common idiom.
45#define CHECK(condition) \
46 do { \
47 if (V8_UNLIKELY(!(condition))) { \
48 V8_Fatal(__FILE__, __LINE__, "Check failed: %s.", #condition); \
49 } \
50 } while (0)
51
52
53#ifdef DEBUG
54
55// Helper macro for binary operators.
56// Don't use this macro directly in your code, use CHECK_EQ et al below.
57#define CHECK_OP(name, op, lhs, rhs) \
58 do { \
59 if (std::string* _msg = ::v8::base::Check##name##Impl( \
60 (lhs), (rhs), #lhs " " #op " " #rhs)) { \
61 V8_Fatal(__FILE__, __LINE__, "Check failed: %s.", _msg->c_str()); \
62 delete _msg; \
63 } \
64 } while (0)
65
66#else
67
68// Make all CHECK functions discard their log strings to reduce code
69// bloat for official release builds.
70
71#define CHECK_OP(name, op, lhs, rhs) CHECK((lhs)op(rhs))
72
73#endif
74
75
76// Build the error message string. This is separate from the "Impl"
77// function template because it is not performance critical and so can
78// be out of line, while the "Impl" code should be inline. Caller
79// takes ownership of the returned string.
80template <typename Lhs, typename Rhs>
81std::string* MakeCheckOpString(Lhs const& lhs, Rhs const& rhs,
82 char const* msg) {
83 std::ostringstream ss;
84 ss << msg << " (" << lhs << " vs. " << rhs << ")";
85 return new std::string(ss.str());
86}
87
88// Commonly used instantiations of MakeCheckOpString<>. Explicitly instantiated
89// in logging.cc.
90#define DEFINE_MAKE_CHECK_OP_STRING(type) \
91 extern template std::string* MakeCheckOpString<type, type>( \
92 type const&, type const&, char const*);
93DEFINE_MAKE_CHECK_OP_STRING(int)
94DEFINE_MAKE_CHECK_OP_STRING(long) // NOLINT(runtime/int)
95DEFINE_MAKE_CHECK_OP_STRING(long long) // NOLINT(runtime/int)
96DEFINE_MAKE_CHECK_OP_STRING(unsigned int)
97DEFINE_MAKE_CHECK_OP_STRING(unsigned long) // NOLINT(runtime/int)
98DEFINE_MAKE_CHECK_OP_STRING(unsigned long long) // NOLINT(runtime/int)
99DEFINE_MAKE_CHECK_OP_STRING(char const*)
100DEFINE_MAKE_CHECK_OP_STRING(void const*)
101#undef DEFINE_MAKE_CHECK_OP_STRING
102
103
104// Helper functions for CHECK_OP macro.
105// The (int, int) specialization works around the issue that the compiler
106// will not instantiate the template version of the function on values of
107// unnamed enum type - see comment below.
108// The (float, float) and (double, double) instantiations are explicitly
109// externialized to ensure proper 32/64-bit comparisons on x86.
110#define DEFINE_CHECK_OP_IMPL(NAME, op) \
111 template <typename Lhs, typename Rhs> \
112 V8_INLINE std::string* Check##NAME##Impl(Lhs const& lhs, Rhs const& rhs, \
113 char const* msg) { \
114 return V8_LIKELY(lhs op rhs) ? nullptr : MakeCheckOpString(lhs, rhs, msg); \
115 } \
116 V8_INLINE std::string* Check##NAME##Impl(int lhs, int rhs, \
117 char const* msg) { \
118 return V8_LIKELY(lhs op rhs) ? nullptr : MakeCheckOpString(lhs, rhs, msg); \
119 } \
120 extern template std::string* Check##NAME##Impl<float, float>( \
121 float const& lhs, float const& rhs, char const* msg); \
122 extern template std::string* Check##NAME##Impl<double, double>( \
123 double const& lhs, double const& rhs, char const* msg);
124DEFINE_CHECK_OP_IMPL(EQ, ==)
125DEFINE_CHECK_OP_IMPL(NE, !=)
126DEFINE_CHECK_OP_IMPL(LE, <=)
127DEFINE_CHECK_OP_IMPL(LT, < )
128DEFINE_CHECK_OP_IMPL(GE, >=)
129DEFINE_CHECK_OP_IMPL(GT, > )
130#undef DEFINE_CHECK_OP_IMPL
131
132#define CHECK_EQ(lhs, rhs) CHECK_OP(EQ, ==, lhs, rhs)
133#define CHECK_NE(lhs, rhs) CHECK_OP(NE, !=, lhs, rhs)
134#define CHECK_LE(lhs, rhs) CHECK_OP(LE, <=, lhs, rhs)
135#define CHECK_LT(lhs, rhs) CHECK_OP(LT, <, lhs, rhs)
136#define CHECK_GE(lhs, rhs) CHECK_OP(GE, >=, lhs, rhs)
137#define CHECK_GT(lhs, rhs) CHECK_OP(GT, >, lhs, rhs)
138#define CHECK_NULL(val) CHECK((val) == nullptr)
139#define CHECK_NOT_NULL(val) CHECK((val) != nullptr)
140#define CHECK_IMPLIES(lhs, rhs) CHECK(!(lhs) || (rhs))
141
142
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000143// Exposed for making debugging easier (to see where your function is being
144// called, just add a call to DumpBacktrace).
145void DumpBacktrace();
146
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000147} // namespace base
148} // namespace v8
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000149
150
151// The DCHECK macro is equivalent to CHECK except that it only
152// generates code in debug builds.
153#ifdef DEBUG
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000154#define DCHECK(condition) CHECK(condition)
155#define DCHECK_EQ(v1, v2) CHECK_EQ(v1, v2)
156#define DCHECK_NE(v1, v2) CHECK_NE(v1, v2)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000157#define DCHECK_GT(v1, v2) CHECK_GT(v1, v2)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000158#define DCHECK_GE(v1, v2) CHECK_GE(v1, v2)
159#define DCHECK_LT(v1, v2) CHECK_LT(v1, v2)
160#define DCHECK_LE(v1, v2) CHECK_LE(v1, v2)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000161#define DCHECK_NULL(val) CHECK_NULL(val)
162#define DCHECK_NOT_NULL(val) CHECK_NOT_NULL(val)
163#define DCHECK_IMPLIES(v1, v2) CHECK_IMPLIES(v1, v2)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000164#else
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000165#define DCHECK(condition) ((void) 0)
166#define DCHECK_EQ(v1, v2) ((void) 0)
167#define DCHECK_NE(v1, v2) ((void) 0)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000168#define DCHECK_GT(v1, v2) ((void) 0)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000169#define DCHECK_GE(v1, v2) ((void) 0)
170#define DCHECK_LT(v1, v2) ((void) 0)
171#define DCHECK_LE(v1, v2) ((void) 0)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000172#define DCHECK_NULL(val) ((void) 0)
173#define DCHECK_NOT_NULL(val) ((void) 0)
174#define DCHECK_IMPLIES(v1, v2) ((void) 0)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000175#endif
176
177#endif // V8_BASE_LOGGING_H_