1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_BASE_LOGGING_H_
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_BASE_LOGGING_H_
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <cstring>
9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <sstream>
10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <string>
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
12c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/base/base-export.h"
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/build_config.h"
14bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#include "src/base/compiler-specific.h"
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
16c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochextern "C" PRINTF_FORMAT(3, 4) V8_NORETURN V8_BASE_EXPORT
17bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    void V8_Fatal(const char* file, int line, const char* format, ...);
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The FATAL, UNREACHABLE and UNIMPLEMENTED macros are useful during
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// development, but they should not be relied on in the final product.
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define FATAL(msg)                              \
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V8_Fatal(__FILE__, __LINE__, "%s", (msg))
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define UNIMPLEMENTED()                         \
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V8_Fatal(__FILE__, __LINE__, "unimplemented code")
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define UNREACHABLE()                           \
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V8_Fatal(__FILE__, __LINE__, "unreachable code")
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define FATAL(msg)                              \
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V8_Fatal("", 0, "%s", (msg))
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define UNIMPLEMENTED()                         \
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V8_Fatal("", 0, "unimplemented code")
33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define UNREACHABLE() V8_Fatal("", 0, "unreachable code")
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace v8 {
38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace base {
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// CHECK dies with a fatal error if condition is not true.  It is *not*
41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// controlled by DEBUG, so the check will be executed regardless of
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// compilation mode.
43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//
44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// We make sure CHECK et al. always evaluates their arguments, as
45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// doing CHECK(FunctionWithSideEffect()) is a common idiom.
46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define CHECK(condition)                                             \
47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  do {                                                               \
48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (V8_UNLIKELY(!(condition))) {                                 \
49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      V8_Fatal(__FILE__, __LINE__, "Check failed: %s.", #condition); \
50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }                                                                \
51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } while (0)
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifdef DEBUG
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Helper macro for binary operators.
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Don't use this macro directly in your code, use CHECK_EQ et al below.
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define CHECK_OP(name, op, lhs, rhs)                                    \
59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  do {                                                                  \
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (std::string* _msg = ::v8::base::Check##name##Impl(              \
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            (lhs), (rhs), #lhs " " #op " " #rhs)) {                     \
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      V8_Fatal(__FILE__, __LINE__, "Check failed: %s.", _msg->c_str()); \
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      delete _msg;                                                      \
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }                                                                   \
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } while (0)
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#else
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Make all CHECK functions discard their log strings to reduce code
70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// bloat for official release builds.
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define CHECK_OP(name, op, lhs, rhs) CHECK((lhs)op(rhs))
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Build the error message string.  This is separate from the "Impl"
78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// function template because it is not performance critical and so can
79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// be out of line, while the "Impl" code should be inline. Caller
80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// takes ownership of the returned string.
81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <typename Lhs, typename Rhs>
82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstd::string* MakeCheckOpString(Lhs const& lhs, Rhs const& rhs,
83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               char const* msg) {
84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostringstream ss;
85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ss << msg << " (" << lhs << " vs. " << rhs << ")";
86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return new std::string(ss.str());
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Commonly used instantiations of MakeCheckOpString<>. Explicitly instantiated
90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// in logging.cc.
91c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#define DEFINE_MAKE_CHECK_OP_STRING(type)                                    \
92c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  extern template V8_BASE_EXPORT std::string* MakeCheckOpString<type, type>( \
93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      type const&, type const&, char const*);
94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDEFINE_MAKE_CHECK_OP_STRING(int)
95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDEFINE_MAKE_CHECK_OP_STRING(long)       // NOLINT(runtime/int)
96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDEFINE_MAKE_CHECK_OP_STRING(long long)  // NOLINT(runtime/int)
97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDEFINE_MAKE_CHECK_OP_STRING(unsigned int)
98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDEFINE_MAKE_CHECK_OP_STRING(unsigned long)       // NOLINT(runtime/int)
99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDEFINE_MAKE_CHECK_OP_STRING(unsigned long long)  // NOLINT(runtime/int)
100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDEFINE_MAKE_CHECK_OP_STRING(char const*)
101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDEFINE_MAKE_CHECK_OP_STRING(void const*)
102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef DEFINE_MAKE_CHECK_OP_STRING
103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Helper functions for CHECK_OP macro.
106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// The (int, int) specialization works around the issue that the compiler
107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// will not instantiate the template version of the function on values of
108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// unnamed enum type - see comment below.
109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// The (float, float) and (double, double) instantiations are explicitly
110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// externialized to ensure proper 32/64-bit comparisons on x86.
111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DEFINE_CHECK_OP_IMPL(NAME, op)                                         \
112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  template <typename Lhs, typename Rhs>                                        \
113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V8_INLINE std::string* Check##NAME##Impl(Lhs const& lhs, Rhs const& rhs,     \
114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           char const* msg) {                  \
115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return V8_LIKELY(lhs op rhs) ? nullptr : MakeCheckOpString(lhs, rhs, msg); \
116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }                                                                            \
117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V8_INLINE std::string* Check##NAME##Impl(int lhs, int rhs,                   \
118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           char const* msg) {                  \
119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return V8_LIKELY(lhs op rhs) ? nullptr : MakeCheckOpString(lhs, rhs, msg); \
120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }                                                                            \
121c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  extern template V8_BASE_EXPORT std::string* Check##NAME##Impl<float, float>( \
122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      float const& lhs, float const& rhs, char const* msg);                    \
123c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  extern template V8_BASE_EXPORT std::string*                                  \
124c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      Check##NAME##Impl<double, double>(double const& lhs, double const& rhs,  \
125c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                        char const* msg);
126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDEFINE_CHECK_OP_IMPL(EQ, ==)
127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDEFINE_CHECK_OP_IMPL(NE, !=)
128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDEFINE_CHECK_OP_IMPL(LE, <=)
129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDEFINE_CHECK_OP_IMPL(LT, < )
130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDEFINE_CHECK_OP_IMPL(GE, >=)
131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDEFINE_CHECK_OP_IMPL(GT, > )
132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef DEFINE_CHECK_OP_IMPL
133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define CHECK_EQ(lhs, rhs) CHECK_OP(EQ, ==, lhs, rhs)
135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define CHECK_NE(lhs, rhs) CHECK_OP(NE, !=, lhs, rhs)
136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define CHECK_LE(lhs, rhs) CHECK_OP(LE, <=, lhs, rhs)
137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define CHECK_LT(lhs, rhs) CHECK_OP(LT, <, lhs, rhs)
138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define CHECK_GE(lhs, rhs) CHECK_OP(GE, >=, lhs, rhs)
139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define CHECK_GT(lhs, rhs) CHECK_OP(GT, >, lhs, rhs)
140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define CHECK_NULL(val) CHECK((val) == nullptr)
141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define CHECK_NOT_NULL(val) CHECK((val) != nullptr)
142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define CHECK_IMPLIES(lhs, rhs) CHECK(!(lhs) || (rhs))
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Exposed for making debugging easier (to see where your function is being
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// called, just add a call to DumpBacktrace).
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid DumpBacktrace();
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace base
150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The DCHECK macro is equivalent to CHECK except that it only
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// generates code in debug builds.
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DCHECK(condition)      CHECK(condition)
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DCHECK_EQ(v1, v2)      CHECK_EQ(v1, v2)
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DCHECK_NE(v1, v2)      CHECK_NE(v1, v2)
159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DCHECK_GT(v1, v2)      CHECK_GT(v1, v2)
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DCHECK_GE(v1, v2)      CHECK_GE(v1, v2)
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DCHECK_LT(v1, v2)      CHECK_LT(v1, v2)
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DCHECK_LE(v1, v2)      CHECK_LE(v1, v2)
163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DCHECK_NULL(val)       CHECK_NULL(val)
164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DCHECK_NOT_NULL(val)   CHECK_NOT_NULL(val)
165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DCHECK_IMPLIES(v1, v2) CHECK_IMPLIES(v1, v2)
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DCHECK(condition)      ((void) 0)
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DCHECK_EQ(v1, v2)      ((void) 0)
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DCHECK_NE(v1, v2)      ((void) 0)
170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DCHECK_GT(v1, v2)      ((void) 0)
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DCHECK_GE(v1, v2)      ((void) 0)
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DCHECK_LT(v1, v2)      ((void) 0)
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DCHECK_LE(v1, v2)      ((void) 0)
174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DCHECK_NULL(val)       ((void) 0)
175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DCHECK_NOT_NULL(val)   ((void) 0)
176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DCHECK_IMPLIES(v1, v2) ((void) 0)
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // V8_BASE_LOGGING_H_
180