Arquivos
hhvm/hphp/util/trace.cpp
T
bsimmers f928f1b320 Support interpOne in translateRegion
This was going to be easy, but then it wasn't. The existing
interpOne relied heavily on the outputs of NormalizedInstruction, and
those are only populated by code that we want to kill soon. It also
didn't properly deal with bytecodes that wrote to more than one local,
or more than one stack cell. So the bulk of this diff is rewriting
interpOne to not rely on the NI outputs, then it was simple to hook it
into the region translator. I also cleaned things up so we don't
attempt to translate instructions that have no hope of succeeding; we
just interp them on the first try now.
2013-06-27 10:38:22 -07:00

168 linhas
4.2 KiB
C++

/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 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. |
+----------------------------------------------------------------------+
*/
/*
* Forcibly define USE_TRACE, so we get the debug trace.h interface included
* here. This allows mixed compilation, where some units were compiled
* DEBUG and others compiled RELEASE, to successfully link.
*/
#ifndef USE_TRACE
# define USE_TRACE 1
#endif
#include "hphp/util/trace.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string>
#include "hphp/util/ringbuffer.h"
namespace HPHP {
TRACE_SET_MOD(tprefix);
namespace Trace {
int levels[NumModules];
static FILE* out;
const char *tokNames[] = {
#define TM(x) #x,
TRACE_MODULES
#undef TM
};
/*
* Dummy class to get some code to run before main().
*/
class Init {
Module name2mod(const char *name) {
for (int i = 0; i < NumModules; i++) {
if (!strcasecmp(tokNames[i], name)) {
return (Module)i;
}
}
return (Module)-1;
}
public:
Init() {
/* Parse the environment for flags. */
const char *envName = "TRACE";
const char *env = getenv(envName);
const char *file = getenv("HPHP_TRACE_FILE");
if (!file) file = "/tmp/hphp.log";
if (env) {
out = fopen(file, "w");
if (!out) {
fprintf(stderr, "could not create log file (%s); using stderr\n", file);
out = stderr;
}
char *e = strdup(env);
char *tok;
for (tok = strtok(e, ","); tok; tok = strtok(nullptr, ",")) {
char *ctok;
char *moduleName = tok;
if (( ctok = strchr(moduleName, ':'))) {
*ctok++ = 0;
}
int level = ctok ? atoi(ctok) : 1;
int mod = name2mod(moduleName);
if (mod >= 0) {
levels[mod] = level;
}
if (mod == Trace::minstr ||
mod == Trace::interpOne) {
levels[Trace::statgroups] = std::max(levels[Trace::statgroups], 1);
}
}
free(e);
} else {
// If TRACE env var is not set, nothing should be traced...
// but if it does, use stderr.
out = stderr;
}
}
};
Init i;
const char* moduleName(Module mod) {
return tokNames[mod];
}
void flush() {
if (!moduleEnabledRelease(Trace::traceAsync)) {
fflush(out);
}
}
void vtrace(const char *fmt, va_list ap) {
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
if (moduleEnabledRelease(Trace::ringbuffer, 1)) {
vtraceRingbuffer(fmt, ap);
} else {
ONTRACE(1, pthread_mutex_lock(&mtx));
ONTRACE(1, fprintf(out, "t%#08x: ",
int((int64_t)pthread_self() & 0xFFFFFFFF)));
vfprintf(out, fmt, ap);
ONTRACE(1, pthread_mutex_unlock(&mtx));
flush();
}
}
void trace(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vtrace(fmt, ap);
va_end(ap);
}
void traceRelease(const char* fmt, ...) {
va_list ap;
va_start(ap, fmt);
vtrace(fmt, ap);
va_end(ap);
}
void traceRingBufferRelease(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vtraceRingbuffer(fmt, ap);
va_end(ap);
}
void trace(const std::string& s) {
trace("%s", s.c_str());
}
void traceRelease(const std::string& s) {
traceRelease("%s", s.c_str());
}
template<>
std::string prettyNode(const char* name, const std::string& s) {
using std::string;
return string("(") + string(name) + string(" ") +
s +
string(")");
}
} } // HPHP::Trace