Skip to content

Commit

Permalink
record an rds::Symbol for every rds::Link
Browse files Browse the repository at this point in the history
Summary:
also unconditionally fill the Symbol -> Handle map.

we do this so that we can identify each handle when creating an RDS
access profile.

Differential Revision: D20810174

fbshipit-source-id: f264803c85980702032da7d844167455070e7bc3
  • Loading branch information
mxw authored and facebook-github-bot committed Apr 22, 2020
1 parent 8e047f9 commit 588cdcb
Show file tree
Hide file tree
Showing 20 changed files with 120 additions and 72 deletions.
2 changes: 1 addition & 1 deletion hphp/runtime/base/enum-cache.cpp
Expand Up @@ -115,7 +115,7 @@ const EnumValues* EnumCache::cacheRequestEnumValues(
assertx(names.isDictOrDArray());
assertx(values.isDictOrDArray());

m_nonScalarEnumValuesMap.bind(rds::Mode::Normal);
m_nonScalarEnumValuesMap.bind(rds::Mode::Normal, rds::LinkID{"EnumCache"});
if (!m_nonScalarEnumValuesMap.isInit()) {
m_nonScalarEnumValuesMap.initWith(req::make_raw<ReqEnumValuesMap>());
}
Expand Down
9 changes: 7 additions & 2 deletions hphp/runtime/base/intercept.cpp
Expand Up @@ -236,9 +236,14 @@ void rename_function(const String& old_name, const String& new_name) {
raise_error("Function already defined: %s", n3w->data());
}

always_assert(!rds::isPersistentHandle(oldNe->getFuncHandle()));
always_assert(
!rds::isPersistentHandle(oldNe->getFuncHandle(func->fullName()))
);
oldNe->setCachedFunc(nullptr);
newNe->m_cachedFunc.bind(rds::Mode::Normal);
newNe->m_cachedFunc.bind(
rds::Mode::Normal,
rds::LinkName{"NEFunc", fnew ? fnew->fullName() : makeStaticString(n3w)}
);
newNe->setCachedFunc(func);

if (RuntimeOption::EvalJit) {
Expand Down
9 changes: 2 additions & 7 deletions hphp/runtime/base/rds-inl.h
Expand Up @@ -39,8 +39,7 @@ Handle bindImpl(Symbol key, Mode mode, size_t sizeBytes,
Handle attachImpl(Symbol key);

void bindOnLinkImpl(std::atomic<Handle>& handle,
folly::Optional<Symbol> key,
Mode mode, size_t size, size_t align,
Symbol key, Mode mode, size_t size, size_t align,
type_scan::Index tsi, const void* init_val);

extern size_t s_normal_frontier;
Expand Down Expand Up @@ -269,18 +268,14 @@ bool Link<T,M>::isPersistent() const {

template<class T, Mode M>
template<size_t Align>
void Link<T,M>::bind(Mode mode,
folly::Optional<Symbol> sym,
const T* init_val) {
void Link<T,M>::bind(Mode mode, Symbol sym, const T* init_val) {
assertx(maybe<M>(mode));
if (LIKELY(bound())) return;

detail::bindOnLinkImpl(
m_handle, sym, mode, sizeof(T), Align,
type_scan::getIndexForScan<T>(), init_val
);
if (!sym) recordRds(m_handle, sizeof(T), "Unknown", __PRETTY_FUNCTION__);

checkSanity();
}

Expand Down
18 changes: 8 additions & 10 deletions hphp/runtime/base/rds.cpp
Expand Up @@ -78,9 +78,7 @@ struct SymbolKind : boost::static_visitor<std::string> {

struct SymbolRep : boost::static_visitor<std::string> {
std::string operator()(LinkName k) const { return k.name->data(); }
std::string operator()(LinkID k) const {
return folly::to<std::string>(k.id);
}
std::string operator()(LinkID k) const { return ""; }

std::string operator()(ClsConstant k) const {
return k.clsName->data() + std::string("::") + k.cnsName->data();
Expand Down Expand Up @@ -134,7 +132,7 @@ struct SymbolEq : boost::static_visitor<bool> {
return strcmp(k1.type, k2.type) == 0 && k1.name->isame(k2.name);
}
bool operator()(LinkID k1, LinkID k2) const {
return strcmp(k1.type, k2.type) == 0 && k1.id == k2.id;
return strcmp(k1.type, k2.type) == 0;
}

bool operator()(ClsConstant k1, ClsConstant k2) const {
Expand Down Expand Up @@ -189,7 +187,7 @@ struct SymbolHash : boost::static_visitor<size_t> {
std::string{k.type}, k.name->hash());
}
size_t operator()(LinkID k) const {
return folly::hash::hash_combine(std::string{k.type}, k.id);
return folly::hash::hash_combine(std::string{k.type});
}

size_t operator()(ClsConstant k) const {
Expand Down Expand Up @@ -541,6 +539,7 @@ Handle bindImpl(Symbol key, Mode mode, size_t sizeBytes,
if (type_scan::hasScanner(tyIndex)) {
s_handleTable.insert(std::make_pair(handle, key));
}

return handle;
}

Expand All @@ -552,16 +551,15 @@ Handle attachImpl(Symbol key) {

NEVER_INLINE
void bindOnLinkImpl(std::atomic<Handle>& handle,
folly::Optional<Symbol> sym,
Mode mode, size_t size, size_t align,
Symbol sym, Mode mode, size_t size, size_t align,
type_scan::Index tsi, const void* init_val) {
Handle c = kUninitHandle;
if (handle.compare_exchange_strong(c, kBeingBound,
std::memory_order_relaxed,
std::memory_order_relaxed)) {
// we flipped it from kUninitHandle, so we get to fill in the value.
auto const h = allocUnlocked(mode, size, align, tsi);
if (sym) recordRds(h, size, *sym);
recordRds(h, size, sym);

if (init_val != nullptr && isPersistentHandle(h)) {
memcpy(handleToPtr<void, Mode::Persistent>(h), init_val, size);
Expand Down Expand Up @@ -638,7 +636,7 @@ void processInit() {
#endif
addNewPersistentChunk(allocSize),

s_persistentTrue.bind(Mode::Persistent);
s_persistentTrue.bind(Mode::Persistent, LinkID{"RDSTrue"});
*s_persistentTrue = true;

local::RDSInit();
Expand Down Expand Up @@ -891,7 +889,7 @@ std::vector<void*> allTLBases() {
}

folly::Optional<Symbol> reverseLink(Handle handle) {
RevLinkTable::const_accessor acc;
decltype(s_handleTable)::const_accessor acc;
if (s_handleTable.find(acc, handle)) {
return acc->second;
}
Expand Down
5 changes: 2 additions & 3 deletions hphp/runtime/base/rds.h
Expand Up @@ -189,7 +189,7 @@ extern __thread void* tl_base;
/*
* Symbols for rds::Link's.
*/
struct LinkID { const char* type; uint64_t id; };
struct LinkID { const char* type; };
struct LinkName { const char* type; LowStringPtr name; };

/*
Expand Down Expand Up @@ -403,8 +403,7 @@ struct Link {
* Post: bound()
*/
template<size_t Align = alignof(T)>
void bind(Mode mode, folly::Optional<Symbol> sym = folly::none,
const T* init_val = nullptr);
void bind(Mode mode, Symbol sym, const T* init_val = nullptr);

/*
* Dereference a Link and access its RDS memory for the current thread.
Expand Down
10 changes: 5 additions & 5 deletions hphp/runtime/base/static-string-table.cpp
Expand Up @@ -292,7 +292,7 @@ bool bindPersistentCns(const StringData* cnsName, const TypedValue& value) {
assertx(it != s_stringDataMap->end());
it->second.bind<kTVSimdAlign>(
rds::Mode::Persistent,
rds::Symbol{rds::LinkName{"Cns", cnsName}},
rds::LinkName{"Cns", cnsName},
&value
);
return it->second.isPersistent();
Expand All @@ -314,10 +314,10 @@ rds::Handle makeCnsHandle(const StringData* cnsName) {
auto const it = s_stringDataMap->find(cnsName);
assertx(it != s_stringDataMap->end());
if (!it->second.bound()) {
it->second.bind<kTVSimdAlign>(rds::Mode::Normal);

rds::recordRds(it->second.handle(), sizeof(TypedValue),
"Cns", cnsName->slice());
it->second.bind<kTVSimdAlign>(
rds::Mode::Normal,
rds::LinkName{"Cns", cnsName}
);
}
return it->second.handle();
}
Expand Down
9 changes: 6 additions & 3 deletions hphp/runtime/ext/asio/ext_static-wait-handle.cpp
Expand Up @@ -73,9 +73,12 @@ c_StaticWaitHandle* c_StaticWaitHandle::CreateFailed(ObjectData* exception) {
}

void AsioExtension::initStaticWaitHandle() {
c_StaticWaitHandle::NullHandle.bind(rds::Mode::Normal);
c_StaticWaitHandle::TrueHandle.bind(rds::Mode::Normal);
c_StaticWaitHandle::FalseHandle.bind(rds::Mode::Normal);
c_StaticWaitHandle::NullHandle.bind(
rds::Mode::Normal, rds::LinkID{"StaticNullWH"});
c_StaticWaitHandle::TrueHandle.bind(
rds::Mode::Normal, rds::LinkID{"StaticTrueWH"});
c_StaticWaitHandle::FalseHandle.bind(
rds::Mode::Normal, rds::LinkID{"StaticFalseWH"});
}

void AsioExtension::requestInitSingletons() {
Expand Down
2 changes: 1 addition & 1 deletion hphp/runtime/ext/process/ext_process.cpp
Expand Up @@ -478,7 +478,7 @@ bool HHVM_FUNCTION(pcntl_signal,
}

if (!g_signal_handlers.bound()) {
g_signal_handlers.bind(rds::Mode::Normal);
g_signal_handlers.bind(rds::Mode::Normal, rds::LinkID{"SignalHandlers"});
}
if (!g_signal_handlers.isInit()) {
g_signal_handlers.initWith(empty_array());
Expand Down
15 changes: 12 additions & 3 deletions hphp/runtime/vm/class-inl.h
Expand Up @@ -465,21 +465,30 @@ inline const VMFixedVector<const Func*>& Class::pinitVec() const {

inline rds::Handle Class::checkedPropTypeRedefinesHandle() const {
assertx(m_maybeRedefsPropTy);
m_extra->m_checkedPropTypeRedefs.bind(rds::Mode::Normal);
m_extra->m_checkedPropTypeRedefs.bind(
rds::Mode::Normal,
rds::LinkName{"PropTypeRedefs", name()}
);
return m_extra->m_checkedPropTypeRedefs.handle();
}

inline rds::Handle Class::checkedPropInitialValuesHandle() const {
assertx(m_needsPropInitialCheck);
m_extra->m_checkedPropInitialValues.bind(rds::Mode::Normal);
m_extra->m_checkedPropInitialValues.bind(
rds::Mode::Normal,
rds::LinkName{"PropInitialValues", name()}
);
return m_extra->m_checkedPropInitialValues.handle();
}

///////////////////////////////////////////////////////////////////////////////
// Property storage.

inline void Class::initPropHandle() const {
m_propDataCache.bind(rds::Mode::Normal);
m_propDataCache.bind(
rds::Mode::Normal,
rds::LinkName{"PropDataCache", name()}
);
}

inline rds::Handle Class::propHandle() const {
Expand Down
18 changes: 12 additions & 6 deletions hphp/runtime/vm/class.cpp
Expand Up @@ -927,7 +927,7 @@ void Class::checkPropInitialValues() const {
assertx(m_extra.get() != nullptr);

auto extra = m_extra.get();
extra->m_checkedPropInitialValues.bind(rds::Mode::Normal);
checkedPropInitialValuesHandle(); // init handle
if (extra->m_checkedPropInitialValues.isInit()) return;

for (Slot slot = 0; slot < m_declProperties.size(); ++slot) {
Expand Down Expand Up @@ -956,7 +956,7 @@ void Class::checkPropTypeRedefinitions() const {
assertx(m_extra.get() != nullptr);

auto extra = m_extra.get();
extra->m_checkedPropTypeRedefs.bind(rds::Mode::Normal);
checkedPropTypeRedefinesHandle(); // init handle
if (extra->m_checkedPropTypeRedefs.isInit()) return;

if (m_parent->m_maybeRedefsPropTy) m_parent->checkPropTypeRedefinitions();
Expand Down Expand Up @@ -1042,13 +1042,13 @@ void Class::initSPropHandles() const {
"around TypedValue");
propHandle.bind(
rds::Mode::Persistent,
rds::Symbol{rds::SPropCache{this, slot}},
rds::SPropCache{this, slot},
reinterpret_cast<const StaticPropData*>(&sProp.val)
);
} else {
propHandle.bind(
rds::Mode::Local,
rds::Symbol{rds::SPropCache{this, slot}}
rds::SPropCache{this, slot}
);
}
} else {
Expand All @@ -1069,7 +1069,10 @@ void Class::initSPropHandles() const {
// of them.
m_sPropCacheInit = rds::s_persistentTrue;
} else {
m_sPropCacheInit.bind(rds::Mode::Normal);
m_sPropCacheInit.bind(
rds::Mode::Normal,
rds::LinkName{"PropCacheInit", name()}
);
}
rds::recordRds(m_sPropCacheInit.handle(),
sizeof(bool), "SPropCacheInit", name()->slice());
Expand Down Expand Up @@ -1358,7 +1361,10 @@ TypedValue Class::clsCnsGet(const StringData* clsCnsName, ClsCnsLookup what) con
* we'll raise an error. The globals array is never a valid value of a (type)
* constant, so we use it as the marker.
*/
m_nonScalarConstantCache.bind(rds::Mode::Normal);
m_nonScalarConstantCache.bind(
rds::Mode::Normal,
rds::LinkName{"ClassNonScalarCnsCache", name()}
);
auto& clsCnsData = *m_nonScalarConstantCache;
if (m_nonScalarConstantCache.isInit()) {
auto const cCns = clsCnsData->get(clsCnsName);
Expand Down
12 changes: 10 additions & 2 deletions hphp/runtime/vm/jit/guard-type-profile.cpp
Expand Up @@ -36,7 +36,12 @@ rds::Handle guardProfileHandle(Type t) {
t.unspecialize().toString() + (t.isSpecialized() ? "<specialized>" : "")
);
auto const pair = s_map.emplace(name);
if (pair.second) pair.first->second.bind(rds::Mode::Normal);
if (pair.second) {
pair.first->second.bind(
rds::Mode::Normal,
rds::LinkName{"ProfileGuardType", pair.first->first}
);
}
return pair.first->second.handle();
}
}
Expand All @@ -56,7 +61,10 @@ void logGuardProfileData() {
auto& link = pair.second;
// It's possible to see the Link after insertion but before it's bound, so
// make sure it's bound before trying to read from it.
link.bind(rds::Mode::Normal);
link.bind(
rds::Mode::Normal,
rds::LinkName{"ProfileGuardType", pair.first}
);
if (!link.isInit() || *link == 0) continue;

StructuredLogEntry log;
Expand Down
24 changes: 15 additions & 9 deletions hphp/runtime/vm/jit/irlower-lookup-cls-func.cpp
Expand Up @@ -170,26 +170,32 @@ const Func* lookupUnknownFunc(const StringData* name) {

namespace {

template<class T> rds::Handle handleFrom(const NamedEntity* ne);
template<class T> rds::Handle handleFrom(
const NamedEntity* ne,
const StringData* name
);

template<>
rds::Handle handleFrom<Func>(const NamedEntity* ne) {
return ne->getFuncHandle();
rds::Handle handleFrom<Func>(const NamedEntity* ne,
const StringData* name) {
return ne->getFuncHandle(name);
}
template<>
rds::Handle handleFrom<Class>(const NamedEntity* ne) {
return ne->getClassHandle();
rds::Handle handleFrom<Class>(const NamedEntity* ne,
const StringData* name) {
return ne->getClassHandle(name);
}
template<>
rds::Handle handleFrom<RecordDesc>(const NamedEntity* ne) {
return ne->getRecordDescHandle();
rds::Handle handleFrom<RecordDesc>(const NamedEntity* ne,
const StringData* name) {
return ne->getRecordDescHandle(name);
}

template<class T, class SlowPath>
void implLdCached(IRLS& env, const IRInstruction* inst,
const StringData* name, SlowPath fill_cache) {
auto const dst = dstLoc(env, inst, 0).reg();
auto const ch = handleFrom<T>(NamedEntity::get(name));
auto const ch = handleFrom<T>(NamedEntity::get(name), name);
auto& v = vmain(env);

if (rds::isNormalHandle(ch)) {
Expand Down Expand Up @@ -220,7 +226,7 @@ template<class T>
void implLdCachedSafe(IRLS& env, const IRInstruction* inst,
const StringData* name) {
auto const dst = dstLoc(env, inst, 0).reg();
auto const ch = handleFrom<T>(NamedEntity::get(name));
auto const ch = handleFrom<T>(NamedEntity::get(name), name);
auto& v = vmain(env);

if (rds::isNormalHandle(ch)) {
Expand Down
5 changes: 4 additions & 1 deletion hphp/runtime/vm/jit/irlower-minstr.cpp
Expand Up @@ -923,7 +923,10 @@ void cgLdPackedArrayDataElemAddr(IRLS& env, const IRInstruction* inst) {
auto const arrTy = inst->src(0)->type();

if (arrTy.maybe(TPackedArr)) {
s_counter.bind(rds::Mode::Local);
s_counter.bind(
rds::Mode::Local,
rds::LinkID{"PackedArraySampleCounter"}
);

auto const profile = [&] (Vout& v) {
auto const handle = s_counter.handle();
Expand Down
2 changes: 1 addition & 1 deletion hphp/runtime/vm/jit/mcgen.cpp
Expand Up @@ -52,7 +52,7 @@ bool s_inited{false};
void processInit() {
TRACE(1, "mcgen startup\n");

g_unwind_rds.bind(rds::Mode::Normal);
g_unwind_rds.bind(rds::Mode::Normal, rds::LinkID{"Unwind"});

Debug::initDebugInfo();
tc::processInit();
Expand Down
2 changes: 1 addition & 1 deletion hphp/runtime/vm/jit/prof-data-serialize.cpp
Expand Up @@ -590,7 +590,7 @@ Class* read_class_internal(ProfDataDeserializer& ser) {
enumBaseReq->type = dt == KindOfInt64 ?
AnnotType::Int : AnnotType::String;
enumBaseReq->name = preClass->enumBaseTy().typeName();
ne->m_cachedTypeAlias.bind(rds::Mode::Normal);
ne->m_cachedTypeAlias.bind(rds::Mode::Normal, rds::LinkID{"NETypeAlias"});
ne->m_cachedTypeAlias.initWith(*enumBaseReq);
}
}
Expand Down

0 comments on commit 588cdcb

Please sign in to comment.