Move SrcKey out of translator.h and Transl:: @override-unit-failures

I was going to #include translator.h in a header I had for
talking to the region selector thing and decided to just get this over
with instead.  (It shouldn't need to #include that.)  Found a few
other unused things to remove while at it.
Esse commit está contido em:
Jordan DeLong
2013-05-31 17:23:11 -07:00
commit de sgolemon
commit f008eafffe
12 arquivos alterados com 201 adições e 182 exclusões
+2 -1
Ver Arquivo
@@ -18,6 +18,7 @@
#include "hphp/compiler/builtin_symbols.h"
#include "hphp/runtime/vm/event_hook.h"
#include "hphp/runtime/vm/jit/translator-x64.h"
#include "hphp/runtime/vm/srckey.h"
#include "hphp/runtime/vm/member_operations.h"
#include "hphp/runtime/base/code_coverage.h"
#include "hphp/runtime/eval/runtime/file_repository.h"
@@ -1831,7 +1832,7 @@ void VMExecutionContext::enterVMWork(ActRec* enterFnAr) {
assert(start);
tx64->enterTCAfterProlog(start);
} else {
Transl::SrcKey sk(curFunc(), m_pc);
SrcKey sk(curFunc(), m_pc);
tx64->enterTCAtSrcKey(sk);
}
} else {
+9 -8
Ver Arquivo
@@ -82,16 +82,17 @@ void Func::parametersCompat(const PreClass* preClass, const Func* imeth) const {
}
}
static Func::FuncId s_nextFuncId = 0;
static FuncId s_nextFuncId = 0;
void Func::setFuncId(FuncId id) {
assert(m_funcId == InvalidId);
assert(id != InvalidId);
assert(m_funcId == InvalidFuncId);
assert(id != InvalidFuncId);
m_funcId = id;
}
void Func::setNewFuncId() {
assert(m_funcId == InvalidId);
m_funcId = __sync_fetch_and_add(&s_nextFuncId, 1);
assert(m_funcId == InvalidFuncId);
m_funcId = static_cast<FuncId>(__sync_fetch_and_add(&s_nextFuncId, 1));
}
void Func::setFullName() {
@@ -188,7 +189,7 @@ Func::Func(Unit& unit, Id id, int line1, int line2,
, m_maxStackCells(0)
, m_numParams(0)
, m_attrs(attrs)
, m_funcId(InvalidId)
, m_funcId(InvalidFuncId)
, m_hasPrivateAncestor(false)
{
m_shared = new SharedData(nullptr, id, base, past, line1, line2,
@@ -211,7 +212,7 @@ Func::Func(Unit& unit, PreClass* preClass, int line1, int line2, Offset base,
, m_maxStackCells(0)
, m_numParams(0)
, m_attrs(attrs)
, m_funcId(InvalidId)
, m_funcId(InvalidFuncId)
, m_hasPrivateAncestor(false)
{
Id id = -1;
@@ -247,7 +248,7 @@ Func* Func::clone() const {
isClosureBody() || isGeneratorFromClosure()
)) Func(*this);
f->initPrologues(m_numParams, isGenerator());
f->m_funcId = InvalidId;
f->m_funcId = InvalidFuncId;
return f;
}
+7 -4
Ver Arquivo
@@ -29,6 +29,12 @@ static const int kNumFixedPrologues = 6;
typedef TypedValue*(*BuiltinFunction)(ActRec* ar);
/*
* Unique identifier for a Func*.
*/
typedef uint32_t FuncId;
constexpr FuncId InvalidFuncId = FuncId(-1LL);
/*
* Metadata about a php function or object method.
*/
@@ -130,9 +136,6 @@ struct Func {
typedef FixedVector<EHEnt> EHEntVec;
typedef FixedVector<FPIEnt> FPIEntVec;
typedef uint32_t FuncId;
static const FuncId InvalidId = -1LL;
Func(Unit& unit, Id id, int line1, int line2, Offset base,
Offset past, const StringData* name, Attr attrs, bool top,
const StringData* docComment, int numParams, bool isGenerator);
@@ -153,7 +156,7 @@ struct Func {
}
FuncId getFuncId() const {
assert(m_funcId != InvalidId);
assert(m_funcId != InvalidFuncId);
return m_funcId;
}
void setFuncId(FuncId id);
+2 -3
Ver Arquivo
@@ -40,7 +40,7 @@ struct CallRecord {
};
};
typedef hphp_hash_map<SrcKey, CallRecord, SrcKey> CallDB;
typedef hphp_hash_map<SrcKey,CallRecord,SrcKey::Hasher> CallDB;
static CallDB s_callDB;
/* record the max number of args to enable invalidation */
static int s_maxNumArgs;
@@ -110,8 +110,7 @@ static void recordActRecPush(NormalizedInstruction& i,
assert(fpi);
assert(name->isStatic());
assert(sk.offset() == fpi->m_fpushOff);
SrcKey fcall = sk;
fcall.m_offset = fpi->m_fcallOff;
auto const fcall = SrcKey { curFunc(), fpi->m_fcallOff };
assert(isFCallStar(*unit->at(fcall.offset())));
if (clsName) {
const Class* cls = Unit::lookupUniqueClass(clsName);
+1 -1
Ver Arquivo
@@ -2673,7 +2673,7 @@ static void emitExitNoIRStats(Asm& a,
HPHP::Trace::moduleEnabled(HPHP::Trace::stats, 3)) {
Stats::emitInc(a,
Stats::opcodeToIRPreStatCounter(
Op(*func->unit()->at(dest.m_offset))),
Op(*func->unit()->at(dest.offset()))),
-1,
Transl::CC_None,
true);
+1 -1
Ver Arquivo
@@ -26,8 +26,8 @@
#include "hphp/runtime/vm/member_operations.h"
#include "hphp/runtime/vm/jit/runtime-type.h"
#include "hphp/runtime/vm/jit/tracebuilder.h"
#include "hphp/runtime/vm/srckey.h"
using HPHP::Transl::SrcKey;
using HPHP::Transl::NormalizedInstruction;
namespace HPHP {
+4 -4
Ver Arquivo
@@ -339,7 +339,7 @@ TranslatorX64::emitRB(X64Assembler& a,
int arg = 0;
emitImmReg(a, t, argNumToRegName[arg++]);
emitImmReg(a, sk.getFuncId(), argNumToRegName[arg++]);
emitImmReg(a, sk.m_offset, argNumToRegName[arg++]);
emitImmReg(a, sk.offset(), argNumToRegName[arg++]);
a. call((TCA)ringbufferEntry);
}
@@ -1654,7 +1654,7 @@ TranslatorX64::emitPrologue(Func* func, int nPassed) {
emitLea(a, rVmFp, -cellsToBytes(frameCells), rVmSp);
}
Fixup fixup(funcBody.m_offset - func->base(), frameCells);
Fixup fixup(funcBody.offset() - func->base(), frameCells);
// Emit warnings for any missing arguments
if (!func->info()) {
@@ -2476,7 +2476,7 @@ bool TranslatorX64::handleServiceRequest(TReqInfo& info,
* axiom.
*/
assert(numInstrs >= 0);
ONTRACE(5, SrcKey(curFunc(), off).trace("interp: enter\n"));
SKTRACE(5, SrcKey(curFunc(), off), "interp: enter\n");
if (numInstrs) {
s_perfCounters[tpc_interp_instr] += numInstrs;
g_vmContext->dispatchN(numInstrs);
@@ -3451,7 +3451,7 @@ TranslatorX64::translateTracelet(const TranslArgs& args) {
// otherwise there's some chance of hitting in the reader threads whose
// metadata is not yet visible.
TRACE(1, "newTranslation: %p sk: (func %d, bcOff %d)\n",
start, sk.getFuncId(), sk.m_offset);
start, sk.getFuncId(), sk.offset());
srcRec.newTranslation(start);
TRACE(1, "tx64: %zd-byte tracelet\n", a.code.frontier - start);
if (Trace::moduleEnabledRelease(Trace::tcspace, 1)) {
+36 -40
Ver Arquivo
@@ -205,57 +205,25 @@ void Tracelet::print(std::ostream& out) const {
}
}
void
SrcKey::trace(const char *fmt, ...) const {
void sktrace(SrcKey sk, const char *fmt, ...) {
if (!Trace::enabled) {
return;
}
// We don't want to print string literals, so don't pass the unit
string s = instrToString(curUnit()->at(m_offset));
string s = instrToString(curUnit()->at(sk.offset()));
const char *filepath = "*anonFile*";
if (curUnit()->filepath()->data() &&
strlen(curUnit()->filepath()->data()) > 0)
filepath = curUnit()->filepath()->data();
Trace::trace("%s:%llx %6d: %20s ",
filepath, (unsigned long long)getFuncId(),
m_offset, s.c_str());
filepath, (unsigned long long)sk.getFuncId(),
sk.offset(), s.c_str());
va_list a;
va_start(a, fmt);
Trace::vtrace(fmt, a);
va_end(a);
}
void
SrcKey::print(int ninstrs) const {
const Unit* u = curUnit();
Opcode* op = (Opcode*)u->at(m_offset);
std::cerr << u->filepath()->data() << ':' << u->getLineNumber(m_offset)
<< std::endl;
for (int i = 0;
i < ninstrs && (uintptr_t)op < ((uintptr_t)u->entry() + u->bclen());
op += instrLen(op), ++i) {
std::cerr << " " << u->offsetOf(op) << ": " << instrToString(op, u)
<< std::endl;
}
}
std::string
SrcKey::pretty() const {
std::ostringstream result;
const char* filepath = tl_regState == REGSTATE_CLEAN ?
curUnit()->filepath()->data() : "unknown";
result << filepath << ':' << getFuncId() << ':' << m_offset;
return result.str();
}
// advance --
//
// Move over the current instruction pointer.
void
Translator::advance(const Opcode** instrs) {
(*instrs) += instrLen(*instrs);
}
/*
* locPhysicalOffset --
*
@@ -2981,7 +2949,7 @@ static bool checkTaintFuncs(StringData* name) {
static bool shouldAnalyzeCallee(const NormalizedInstruction* fcall) {
auto const numArgs = fcall->imm[0].u_IVA;
auto const target = fcall->funcd;
auto const fpi = curFunc()->findFPI(fcall->source.m_offset);
auto const fpi = curFunc()->findFPI(fcall->source.offset());
auto const pushOp = curUnit()->getOpcode(fpi->m_fpushOff);
if (!RuntimeOption::RepoAuthoritative) return false;
@@ -3387,7 +3355,7 @@ std::unique_ptr<Tracelet> Translator::analyze(SrcKey sk,
if (isFCallStar(ni->op())) {
if (!doVarEnvTaint) {
const FPIEnt *fpi = curFunc()->findFPI(ni->source.m_offset);
const FPIEnt *fpi = curFunc()->findFPI(ni->source.offset());
assert(fpi);
Offset fpushOff = fpi->m_fpushOff;
PC fpushPc = curUnit()->at(fpushOff);
@@ -3480,7 +3448,7 @@ std::unique_ptr<Tracelet> Translator::analyze(SrcKey sk,
SKTRACE(1, sk, "greedily continuing through %dth jmp + %d\n",
tas.m_numJmps, ni->imm[0].u_IA);
tas.recordJmp();
sk = SrcKey(curFunc(), sk.m_offset + ni->imm[0].u_IA);
sk = SrcKey(curFunc(), sk.offset() + ni->imm[0].u_IA);
goto head; // don't advance sk
} else if (opcodeBreaksBB(ni->op()) ||
(dontGuardAnyInputs(ni->op()) && opcodeChangesPC(ni->op()))) {
@@ -3571,7 +3539,7 @@ Translator::isSrcKeyInBL(const Unit* unit, const SrcKey& sk) {
if (m_dbgBLSrcKey.find(sk) != m_dbgBLSrcKey.end()) {
return true;
}
for (PC pc = unit->at(sk.m_offset); !opcodeBreaksBB(*pc);
for (PC pc = unit->at(sk.offset()); !opcodeBreaksBB(*pc);
pc += instrLen(pc)) {
if (m_dbgBLPC.checkPC(pc)) {
m_dbgBLSrcKey.insert(sk);
@@ -3616,6 +3584,34 @@ uint64_t* Translator::getTransCounterAddr() {
[id % transCountersPerChunk]);
}
uint32_t Translator::addTranslation(const TransRec& transRec) {
if (Trace::moduleEnabledRelease(Trace::trans, 1)) {
// Log the translation's size, creation time, SrcKey, and size
Trace::traceRelease("New translation: %lld %s %u %u %d\n",
Timer::GetCurrentTimeMicros() - m_createdTime,
folly::format("{}:{}:{}",
curUnit()->filepath()->data(),
transRec.src.getFuncId(),
transRec.src.offset()).str().c_str(),
transRec.aLen,
transRec.astubsLen,
transRec.kind);
}
if (!isTransDBEnabled()) return -1u;
uint32_t id = getCurrentTransID();
m_translations.push_back(transRec);
m_translations[id].setID(id);
if (transRec.aLen > 0) {
m_transDB[transRec.aStart] = id;
}
if (transRec.astubsLen > 0) {
m_transDB[transRec.astubsStart] = id;
}
return id;
}
uint64_t Translator::getTransCounter(TransID transId) const {
if (!isTransDBEnabled()) return -1ul;
+5 -118
Ver Arquivo
@@ -38,6 +38,7 @@
#include "hphp/runtime/vm/jit/writelease.h"
#include "hphp/runtime/vm/jit/trans-data.h"
#include "hphp/runtime/vm/debugger_hook.h"
#include "hphp/runtime/vm/srckey.h"
#include "hphp/runtime/base/md5.h"
/* Translator front-end. */
@@ -63,98 +64,9 @@ enum VMRegState {
};
extern __thread VMRegState tl_regState;
/*
* A SrcKey is a logical source instruction, currently a unit/instruction pair.
* The units are identified by contents rather than Unit; Unit's are
* ephemeral, and we want to reuse SrcKey's when we encounter Unit's with
* the same contents.
*/
struct SrcKey {
private:
Func::FuncId m_funcId;
public:
Offset m_offset;
SrcKey() : m_funcId(Func::InvalidId), m_offset(0) { }
SrcKey(const Func* f, Offset off) :
m_funcId(f->getFuncId()), m_offset(off) { }
SrcKey(const Func* f, const Opcode* i) :
m_funcId(f->getFuncId()), m_offset(f->unit()->offsetOf(i)) { }
int cmp(const SrcKey &r) const {
// Can't use memcmp because of pad bytes. Frowny.
#define CMP(field) \
if (field < r.field) return -1; \
if (field > r.field) return 1
CMP(getFuncId());
CMP(m_offset);
#undef CMP
return 0;
}
bool operator==(const SrcKey& r) const {
return cmp(r) == 0;
}
bool operator!=(const SrcKey& r) const {
return cmp(r) != 0;
}
bool operator<(const SrcKey& r) const {
return cmp(r) < 0;
}
bool operator>(const SrcKey& r) const {
return cmp(r) > 0;
}
// Hash function for both hash_map and tbb conventions.
static size_t hash(const SrcKey &sk) {
return HPHP::hash_int64_pair(sk.getFuncId(), uint64_t(sk.m_offset));
}
size_t operator()(const SrcKey& sk) const {
return hash(sk);
}
static bool equal(const SrcKey& sk1, const SrcKey& sk2) {
return sk1 == sk2;
}
// Packed representation of SrcKeys for use in contexts where we
// want atomicity. (SrcDB.)
typedef uint64_t AtomicInt;
AtomicInt toAtomicInt() const {
return uint64_t(getFuncId()) << 32 | uint64_t(m_offset);
}
static SrcKey fromAtomicInt(AtomicInt in) {
SrcKey k;
k.setFuncId(in >> 32);
k.m_offset = in & 0xffffffff;
return k;
}
void setFuncId(Func::FuncId id) {
assert(id != Func::InvalidId);
m_funcId = id;
}
Func::FuncId getFuncId() const {
assert(m_funcId != Func::InvalidId);
return m_funcId;
}
void trace(const char *fmt, ...) const;
void print(int ninstr) const;
std::string pretty() const;
int offset() const {
return m_offset;
}
void advance(const Unit* u) {
m_offset += instrLen(u->at(offset()));
}
};
typedef hphp_hash_set<SrcKey, SrcKey> SrcKeySet;
void sktrace(SrcKey sk, const char *fmt, ...);
#define SKTRACE(level, sk, ...) \
ONTRACE(level, (sk).trace(__VA_ARGS__))
ONTRACE(level, sktrace(sk, __VA_ARGS__))
struct NormalizedInstruction;
@@ -893,34 +805,10 @@ public:
}
uint64_t* getTransCounterAddr();
uint64_t getTransCounter(TransID transId) const;
void setTransCounter(TransID transId, uint64_t value);
uint32_t addTranslation(const TransRec& transRec) {
if (Trace::moduleEnabledRelease(Trace::trans, 1)) {
// Log the translation's size, creation time, SrcKey, and size
Trace::traceRelease("New translation: %lld %s %u %u %d\n",
Timer::GetCurrentTimeMicros() - m_createdTime,
transRec.src.pretty().c_str(), transRec.aLen,
transRec.astubsLen, transRec.kind);
}
if (!isTransDBEnabled()) return -1u;
uint32_t id = getCurrentTransID();
m_translations.push_back(transRec);
m_translations[id].setID(id);
if (transRec.aLen > 0) {
m_transDB[transRec.aStart] = id;
}
if (transRec.astubsLen > 0) {
m_transDB[transRec.astubsStart] = id;
}
return id;
}
uint32_t addTranslation(const TransRec& transRec);
/*
* Create a Tracelet for the given SrcKey, which must actually be
@@ -933,7 +821,6 @@ public:
void postAnalyze(NormalizedInstruction* ni, SrcKey& sk,
Tracelet& t, TraceletContext& tas);
void advance(Opcode const **instrs);
static int locPhysicalOffset(Location l, const Func* f = nullptr);
static Location tvToLocation(const TypedValue* tv, const TypedValue* frame);
static bool typeIsString(DataType type) {
@@ -963,7 +850,7 @@ public:
protected:
PCFilter m_dbgBLPC;
SrcKeySet m_dbgBLSrcKey;
hphp_hash_set<SrcKey,SrcKey::Hasher> m_dbgBLSrcKey;
Mutex m_dbgBlacklistLock;
bool isSrcKeyInBL(const Unit* unit, const SrcKey& sk);
+126
Ver Arquivo
@@ -0,0 +1,126 @@
/*
+----------------------------------------------------------------------+
| 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_HPHP_SRCKEY_H_
#define incl_HPHP_SRCKEY_H_
#include <tuple>
#include <boost/operators.hpp>
#include "hphp/runtime/vm/func.h"
#include "hphp/runtime/vm/core_types.h"
namespace HPHP {
//////////////////////////////////////////////////////////////////////
/*
* A SrcKey is a logical source instruction---it's enough to identify
* these using a (Func id, hhbc instruction) pair.
*/
struct SrcKey : private boost::totally_ordered<SrcKey> {
typedef uint64_t AtomicInt;
struct Hasher;
SrcKey()
: m_funcId(InvalidFuncId)
, m_offset(0)
{}
SrcKey(const Func* f, Offset off)
: m_funcId(f->getFuncId())
, m_offset(off)
{}
SrcKey(const Func* f, const Opcode* i)
: m_funcId(f->getFuncId())
, m_offset(f->unit()->offsetOf(i))
{}
SrcKey(FuncId funcId, Offset off)
: m_funcId{funcId}
, m_offset{off}
{}
// Packed representation of SrcKeys for use in contexts where we
// want atomicity. (SrcDB.)
AtomicInt toAtomicInt() const {
return uint64_t(getFuncId()) << 32 | uint64_t(offset());
}
static SrcKey fromAtomicInt(AtomicInt in) {
return SrcKey { uint32_t(in >> 32), uint32_t(in & 0xffffffff) };
}
void setFuncId(FuncId id) {
assert(id != InvalidFuncId);
m_funcId = id;
}
FuncId getFuncId() const {
assert(m_funcId != InvalidFuncId);
return m_funcId;
}
int offset() const {
return m_offset;
}
/*
* Advance the SrcKey to the next instruction.
*
* If the SrcKey points to the last instruction in a function, this
* will advance past the end of the function, and potentially
* contain an invalid bytecode offset.
*/
void advance(const Unit* u) {
m_offset += instrLen(u->at(offset()));
}
/*
* Return a SrcKey representing the next instruction, without
* mutating this SrcKey.
*/
SrcKey advanced(const Unit* u) const {
auto tmp = *this;
tmp.advance(u);
return tmp;
}
bool operator==(const SrcKey& r) const {
return offset() == r.offset() &&
getFuncId() == r.getFuncId();
}
bool operator<(const SrcKey& r) const {
return std::make_tuple(offset(), getFuncId()) <
std::make_tuple(r.offset(), r.getFuncId());
}
private:
FuncId m_funcId;
Offset m_offset;
};
struct SrcKey::Hasher {
size_t operator()(SrcKey sk) const {
return hash_int64_pair(sk.getFuncId(), uint64_t(sk.offset()));
}
};
//////////////////////////////////////////////////////////////////////
}
#endif
+1 -2
Ver Arquivo
@@ -1498,8 +1498,7 @@ bool Unit::getOffsetRange(Offset pc, OffsetRange& range) const {
const Func* Unit::getFunc(Offset pc) const {
FuncEntry key = FuncEntry(pc, nullptr);
FuncTable::const_iterator it =
upper_bound(m_funcTable.begin(), m_funcTable.end(), key);
auto it = std::upper_bound(m_funcTable.begin(), m_funcTable.end(), key);
if (it != m_funcTable.end()) {
assert(pc < it->pastOffset());
return it->val();
+7
Ver Arquivo
@@ -609,7 +609,14 @@ public:
return (Opcode)m_bc[instrOffset];
}
/*
* Return the Func* for the code at offset off.
*
* Returns nullptr if the offset is not in a func body (but this
* should be impossible).
*/
const Func* getFunc(Offset pc) const;
void setCacheId(unsigned id) {
m_cacheOffset = id >> 3;
m_cacheMask = 1 << (id & 7);