diff --git a/hphp/runtime/base/runtime_option.h b/hphp/runtime/base/runtime_option.h index 86d785bed..d838bf013 100644 --- a/hphp/runtime/base/runtime_option.h +++ b/hphp/runtime/base/runtime_option.h @@ -444,6 +444,8 @@ public: F(bool, MapTCHuge, true) \ F(bool, RandomHotFuncs, false) \ F(bool, DisableSomeRepoAuthNotices, true) \ + F(uint32_t, InitialNamedEntityTableSize, 30000) \ + F(uint32_t, InitialStaticStringTableSize, 100000) \ /* */ \ #define F(type, name, unused) \ diff --git a/hphp/runtime/base/server/admin_request_handler.cpp b/hphp/runtime/base/server/admin_request_handler.cpp index 8341bda41..885c94c96 100644 --- a/hphp/runtime/base/server/admin_request_handler.cpp +++ b/hphp/runtime/base/server/admin_request_handler.cpp @@ -14,9 +14,6 @@ +----------------------------------------------------------------------+ */ -#include -#include - #include "hphp/runtime/base/server/admin_request_handler.h" #include "hphp/runtime/eval/runtime/file_repository.h" #include "hphp/runtime/base/server/http_server.h" @@ -46,6 +43,9 @@ #include "hphp/runtime/ext/ext_fb.h" #include "hphp/runtime/ext/ext_apc.h" +#include +#include + #ifdef GOOGLE_CPU_PROFILER #include "google/profiler.h" #endif @@ -214,6 +214,7 @@ void AdminRequestHandler::handleRequest(Transport *transport) { " /tmp/tc_dump_astub\n" "/vm-preconsts: show information about preconsts\n" "/vm-tcreset: throw away translations and start over\n" + "/vm-namedentities:show size of the NamedEntityTable\n" ; #ifdef USE_TCMALLOC if (MallocExtensionInstance) { @@ -962,6 +963,12 @@ bool AdminRequestHandler::handleVMRequest(const std::string &cmd, transport->sendString(Transl::Translator::Get()->getUsage()); return true; } + if (cmd == "vm-namedentities") { + std::ostringstream result; + result << Unit::GetNamedEntityTableSize(); + transport->sendString(result.str()); + return true; + } if (cmd == "vm-preconsts") { InfoMap counts; using namespace HPHP::Transl; diff --git a/hphp/runtime/base/string_data.cpp b/hphp/runtime/base/string_data.cpp index e34318d97..9ab15e82f 100644 --- a/hphp/runtime/base/string_data.cpp +++ b/hphp/runtime/base/string_data.cpp @@ -35,12 +35,19 @@ namespace HPHP { IMPLEMENT_SMART_ALLOCATION_HOT(StringData); /////////////////////////////////////////////////////////////////////////////// -// constructor and destructor + +// equality checker for AtomicHashMap +struct ahm_string_data_same { + bool operator()(const StringData *s1, const StringData *s2) const { + // ahm uses -1, -2, -3 as magic values + return int64_t(s1) > 0 && s1->same(s2); + } +}; // The uint32_t is used to hold TargetCache offsets for constants -typedef tbb::concurrent_unordered_map StringDataMap; +typedef folly::AtomicHashMap StringDataMap; static StringDataMap *s_stringDataMap; const StringData* StringData::convert_double_helper(double n) { @@ -71,7 +78,13 @@ size_t StringData::GetStaticStringCount() { } StringData *StringData::GetStaticString(const StringData *str) { - if (UNLIKELY(!s_stringDataMap)) s_stringDataMap = new StringDataMap(); + if (UNLIKELY(!s_stringDataMap)) { + StringDataMap::Config config; + config.growthFactor = 1; + s_stringDataMap = + new StringDataMap(RuntimeOption::EvalInitialStaticStringTableSize, + config); + } StringDataMap::const_iterator it = s_stringDataMap->find(str); if (it != s_stringDataMap->end()) { return const_cast(it->first); @@ -81,8 +94,7 @@ StringData *StringData::GetStaticString(const StringData *str) { StringData *sd = (StringData*)Util::low_malloc(sizeof(StringData)); new (sd) StringData(str->data(), str->size(), CopyMalloc); sd->setStatic(); - auto pair = s_stringDataMap->insert( - std::pair(sd, 0)); + auto pair = s_stringDataMap->insert(sd, 0); if (!pair.second) { sd->~StringData(); Util::low_free(sd); @@ -97,7 +109,13 @@ StringData* StringData::GetStaticString(const String& str) { } StringData* StringData::FindStaticString(const StringData* str) { - if (UNLIKELY(!s_stringDataMap)) s_stringDataMap = new StringDataMap(); + if (UNLIKELY(!s_stringDataMap)) { + StringDataMap::Config config; + config.growthFactor = 1; + s_stringDataMap = + new StringDataMap(RuntimeOption::EvalInitialStaticStringTableSize, + config); + } StringDataMap::const_iterator it = s_stringDataMap->find(str); if (it != s_stringDataMap->end()) { return const_cast(it->first); diff --git a/hphp/runtime/vm/named_entity.h b/hphp/runtime/vm/named_entity.h index 80703b899..bbfafe5e0 100644 --- a/hphp/runtime/vm/named_entity.h +++ b/hphp/runtime/vm/named_entity.h @@ -23,6 +23,7 @@ #include "hphp/runtime/base/complex_types.h" #include "hphp/util/atomic.h" +#include "folly/AtomicHashMap.h" namespace HPHP { @@ -112,11 +113,18 @@ private: ////////////////////////////////////////////////////////////////////// -typedef tbb::concurrent_unordered_map< +struct ahm_string_data_isame { + bool operator()(const StringData *s1, const StringData *s2) const { + // ahm uses -1, -2, -3 as magic values + return int64_t(s1) > 0 && s1->isame(s2); + } +}; + +typedef folly::AtomicHashMap< const StringData*, NamedEntity, string_data_hash, - string_data_isame + ahm_string_data_isame > NamedEntityMap; typedef std::pair NamedEntityPair; diff --git a/hphp/runtime/vm/unit.cpp b/hphp/runtime/vm/unit.cpp index 6bf82f2df..d691f9eca 100644 --- a/hphp/runtime/vm/unit.cpp +++ b/hphp/runtime/vm/unit.cpp @@ -91,12 +91,23 @@ NamedEntity* getNamedEntityHelper(const StringData* str) { str = StringData::GetStaticString(str); } - return &(*s_namedDataMap)[str]; + auto res = s_namedDataMap->insert(str, NamedEntity()); + return &res.first->second; +} + +size_t Unit::GetNamedEntityTableSize() { + return s_namedDataMap ? s_namedDataMap->size() : 0; } NamedEntity* Unit::GetNamedEntity(const StringData* str) { - if (!s_namedDataMap) s_namedDataMap = new NamedEntityMap(); - NamedEntityMap::const_iterator it = s_namedDataMap->find(str); + if (UNLIKELY(!s_namedDataMap)) { + NamedEntityMap::Config config; + config.growthFactor = 1; + s_namedDataMap = + new NamedEntityMap(RuntimeOption::EvalInitialNamedEntityTableSize, + config); + } + NamedEntityMap::iterator it = s_namedDataMap->find(str); if (LIKELY(it != s_namedDataMap->end())) return &it->second; return getNamedEntityHelper(str); } diff --git a/hphp/runtime/vm/unit.h b/hphp/runtime/vm/unit.h index 03a063078..ff6326ebd 100644 --- a/hphp/runtime/vm/unit.h +++ b/hphp/runtime/vm/unit.h @@ -449,6 +449,7 @@ struct Unit { static NamedEntity* GetNamedEntity(const StringData *) __attribute__((__flatten__)); + static size_t GetNamedEntityTableSize(); static Array getUserFunctions(); static Array getClassesInfo(); static Array getInterfacesInfo();