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