Arquivos
hhvm/hphp/util/trace.h
T
Jordan Delong 363d1bb20f Code move src/ -> hphp/
This change is mostly for FB internal organizational reasons.
Building is not effected beyond the fact that the target now
lands in hphp/hhvm/hhvm rather than src/hhvm/hhvm.
2013-02-11 02:10:41 -08:00

228 linhas
7.3 KiB
C++

/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010- Facebook, Inc. (http://www.facebook.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#ifndef incl_TRACE_H_
#define incl_TRACE_H_
#include <string>
#include <vector>
#include <stdarg.h>
#include "folly/Format.h"
/*
* Runtime-selectable trace facility. A trace statement has both a module and a
* level associated with it; Enable tracing a module by setting the TRACE
* environment variable to a comma-separated list of module:level pairs. E.g.:
*
* env TRACE=tx64:1,bcinterp:3,tmp0:1 ./hhvm/hhvm ...
*
* In a source file, select the compilation unit's module by calling the
* TRACE_SET_MODE macro. E.g.,
*
* TRACE_SET_MOD(tx64);
*
* ...
* TRACE(0, "See this for any trace-enabled build: %d\n", foo);
* TRACE(1, "Trace-level must be 1 or higher for this one\n");
*
* While the levels are arbitrary integers, code so far is following a
* rough convention of 1-5, where 1 is minimal and 5 is quite verbose.
*
* Normally trace information is printed to /tmp/hphp.log. You can
* override the environment variable HPHP_TRACE_FILE to change
* this. (Note you can set it to something like /dev/stderr if you
* want the logs printed to your terminal).
*/
namespace HPHP {
namespace Trace {
#define TRACE_MODULES \
TM(tprefix) /* Meta: prefix with string */ \
TM(ringbuffer) /* Meta: trace to ram */ \
TM(traceAsync) /* Meta: lazy writes to disk */ \
TM(trans) \
TM(tx64) \
TM(tx64stats) \
TM(tunwind) \
TM(txlease) \
TM(fixup) \
TM(tcspace) \
TM(targetcache) \
TM(tcdump) \
TM(treadmill) \
TM(regalloc) \
TM(bcinterp) \
TM(refcount) \
TM(asmx64) \
TM(runtime) \
TM(debuginfo) \
TM(stats) \
TM(emitter) \
TM(hhbc) \
TM(stat) \
TM(fr) \
TM(intercept) \
TM(txdeps) \
TM(typeProfile) \
TM(hhir) \
TM(gc) \
TM(unlikely) \
TM(jcc) \
TM(instancebits)\
TM(hhas) \
TM(punt) \
/* Stress categories, to exercise rare paths */ \
TM(stress_txInterpPct) \
TM(stress_txInterpSeed) \
/* Jit bisection interval */ \
TM(txOpBisectLow) \
TM(txOpBisectHigh) \
/* Temporary catetories, to save compilation time */ \
TM(tmp0) TM(tmp1) TM(tmp2) TM(tmp3) \
TM(tmp4) TM(tmp5) TM(tmp6) TM(tmp7) \
TM(tmp8) TM(tmp9) TM(tmp10) TM(tmp11) \
TM(tmp12) TM(tmp13) TM(tmp14) TM(tmp15)
enum Module {
#define TM(x) \
x,
TRACE_MODULES
#undef TM
NumModules
};
/*
* S-expression style structured pretty-printing. Implement
* std::string pretty() const { }, with the convention that
* nested structures are notated as lisp-style trees:
*
* (<typename> field0 field1)
*
* E.g.:
* (Location Stack 1)
* (RuntimeType (Location Stack 1) (Home (Location Local 1)))
*
* The repetitve prettyNode() templates are intended to aid
* implementing pretty().
*/
template<typename P1>
std::string prettyNode(const char* name, const std::vector<P1>& vec) {
using std::string;
std::string retval = string("(") + string(name) + string(" ");
for(size_t i = 0; i < vec.size(); i++) {
retval += vec[i].pretty();
if (i != vec.size() - 1) {
retval += string(" ");
}
}
return retval + string(")");
}
template<typename P1>
std::string prettyNode(const char* name, const P1& p1) {
using std::string;
return string("(") + string(name) + string(" ") +
p1.pretty() +
string(")");
}
template<> std::string prettyNode(const char* name, const std::string& s);
template<typename P1, typename P2>
std::string prettyNode(const char* name, const P1& p1, const P2& p2) {
using std::string;
return string("(") + string(name) + string(" ") +
p1.pretty() + string(" ") + p2.pretty() +
string(")");
}
extern void traceRelease(const char*, ...);
extern int levels[NumModules];
extern const char* moduleName(Module mod);
static inline bool moduleEnabledRelease(Module tm, int level = 1) {
return levels[tm] >= level;
}
#if (defined(DEBUG) || defined(USE_TRACE)) /* { */
# ifndef USE_TRACE
# define USE_TRACE 1
# endif
static inline bool moduleEnabled(Module tm, int level = 1) {
return moduleEnabledRelease(tm, level);
}
static inline int moduleLevel(Module tm) { return levels[tm]; }
#define HPHP_TRACE
static const bool enabled = true;
#define ONTRACE_MOD(module, n, x) do { \
if (HPHP::Trace::moduleEnabled(module, n)) { \
x; \
} } while(0)
#define ONTRACE(n, x) ONTRACE_MOD(TRACEMOD, n, x)
#define TRACE(n, ...) ONTRACE(n, HPHP::Trace::trace(__VA_ARGS__))
#define FTRACE(n, ...) \
ONTRACE(n, HPHP::Trace::trace("%s", \
folly::format(__VA_ARGS__).str().c_str()))
#define TRACE_MOD(mod, level, ...) \
ONTRACE_MOD(mod, level, HPHP::Trace::trace(__VA_ARGS__))
#define FTRACE_MOD(mod, level, ...) \
ONTRACE_MOD(mod, level, HPHP::Trace::trace("%s", \
folly::format(__VA_ARGS__).str().c_str()))
#define TRACE_SET_MOD(name) \
static const HPHP::Trace::Module TRACEMOD = HPHP::Trace::name;
extern void trace(const char *, ...)
__attribute__((format(printf,1,2)));
extern void trace(const std::string&);
template<typename Pretty>
static inline void trace(Pretty p) { trace(p.pretty() + std::string("\n")); }
extern void vtrace(const char *fmt, va_list args);
extern void dumpRingbuffer();
#else /* } (defined(DEBUG) || defined(USE_TRACE)) { */
/*
* Compile everything out of release builds. gcc is smart enough to
* kill code hiding behind if (false) { ... }.
*/
#define ONTRACE(...) do { } while (0)
#define TRACE(...) do { } while (0)
#define FTRACE(...) do { } while (0)
#define TRACE_MOD(...) do { } while (0)
#define FTRACE_MOD(...) do { } while (0)
#define TRACE_SET_MOD(...) /* nil */
static const bool enabled = false;
static inline void trace(const char*, ...) { }
static inline void trace(const std::string&) { }
static inline void vtrace(const char*, va_list) { }
static inline bool moduleEnabled(Module t, int level = 1) { return false; }
static inline int moduleLevel(Module tm) { return 0; }
#endif /* } (defined(DEBUG) || defined(USE_TRACE)) */
} } // HPHP::Trace
#endif /* incl_TRACE_H_ */