Use AtomicHashMap for NamedEntities and StaticStrings
Its faster as long as you have a good starting point. Add RuntimeOptions to specify initial sizes.
Esse commit está contido em:
@@ -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) \
|
||||
|
||||
@@ -14,9 +14,6 @@
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#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 <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#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;
|
||||
|
||||
@@ -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<const StringData *, uint32_t,
|
||||
string_data_hash,
|
||||
string_data_same> StringDataMap;
|
||||
typedef folly::AtomicHashMap<const StringData *, uint32_t,
|
||||
string_data_hash,
|
||||
ahm_string_data_same> 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<StringData*>(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<const StringData*,uint32_t>(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<StringData*>(it->first);
|
||||
|
||||
@@ -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<const StringData*,const NamedEntity*> NamedEntityPair;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário