diff --git a/hphp/runtime/base/execution-context.cpp b/hphp/runtime/base/execution-context.cpp index 69ad154467f491..aa8dad69499967 100644 --- a/hphp/runtime/base/execution-context.cpp +++ b/hphp/runtime/base/execution-context.cpp @@ -2007,6 +2007,16 @@ typedef RankedCHM EvaledUnitsMap; static EvaledUnitsMap s_evaledUnits; +static std::atomic s_createfuncs; + +int64_t getEvaledUnits() { + return s_evaledUnits.size(); +} + +int64_t getCreateFuncs() { + return s_createfuncs.load(std::memory_order_acquire); +} + Unit* ExecutionContext::compileEvalString( StringData* code, const char* evalFilename /* = nullptr */) { @@ -2015,6 +2025,11 @@ Unit* ExecutionContext::compileEvalString( // across requests. code = makeStaticString(code); if (s_evaledUnits.insert(acc, code)) { + if (RuntimeOption::EnableDynamicFuncWarn) { + Logger::Warning("Don't recommended call eval(), " + "maybe effect performance " + "in %s on %d", getContainingFileName()->data(), getLine()); + } acc->second = compile_string( code->data(), code->size(), @@ -2034,6 +2049,12 @@ StrNR ExecutionContext::createFunction(const String& args, } VMRegAnchor _; + s_createfuncs.fetch_add(1, std::memory_order_acq_rel); + if (RuntimeOption::EnableDynamicFuncWarn) { + Logger::Warning("Don't recommended call eval(), " + "maybe effect performance " + "in %s on %d", getContainingFileName()->data(), getLine()); + } auto const ar = GetCallerFrame(); // It doesn't matter if there's a user function named __lambda_func; we only // use this name during parsing, and then change it to an impossible name diff --git a/hphp/runtime/base/execution-context.h b/hphp/runtime/base/execution-context.h index f4f83b0a034198..c7b9d3833d6f2c 100644 --- a/hphp/runtime/base/execution-context.h +++ b/hphp/runtime/base/execution-context.h @@ -66,6 +66,9 @@ enum class InclOpFlags { Relative = 16, }; +int64_t getEvaledUnits(); +int64_t getCreateFuncs(); + inline InclOpFlags operator|(const InclOpFlags& l, const InclOpFlags& r) { return static_cast(static_cast(l) | static_cast(r)); } diff --git a/hphp/runtime/base/runtime-option.cpp b/hphp/runtime/base/runtime-option.cpp index 35ca731c9d744f..b966713ca4c2b4 100644 --- a/hphp/runtime/base/runtime-option.cpp +++ b/hphp/runtime/base/runtime-option.cpp @@ -107,6 +107,7 @@ bool RuntimeOption::CheckFlushOnUserClose = true; bool RuntimeOption::EvalAuthoritativeMode = false; bool RuntimeOption::IntsOverflowToInts = false; bool RuntimeOption::AutoprimeGenerators = true; +bool RuntimeOption::EnableDynamicFuncWarn = false; #ifdef FACEBOOK bool RuntimeOption::UseThriftLogger = false; @@ -1138,6 +1139,8 @@ void RuntimeOption::Load( } { // Eval + Config::Bind(EnableDynamicFuncWarn, ini, config, "Eval.EnableDynamicFuncWarn", + EnableDynamicFuncWarn); Config::Bind(EnableHipHopSyntax, ini, config, "Eval.EnableHipHopSyntax", EnableHipHopSyntax); Config::Bind(EnableHipHopExperimentalSyntax, ini, diff --git a/hphp/runtime/base/runtime-option.h b/hphp/runtime/base/runtime-option.h index 1f2546ca458253..4f80ee9f8d6666 100644 --- a/hphp/runtime/base/runtime-option.h +++ b/hphp/runtime/base/runtime-option.h @@ -379,6 +379,7 @@ struct RuntimeOption { // is the following prefix followed by the pid of the hphp process. static std::string LightProcessFilePrefix; static int LightProcessCount; + static bool EnableDynamicFuncWarn; // Eval options static bool EnableHipHopSyntax; diff --git a/hphp/runtime/server/admin-request-handler.cpp b/hphp/runtime/server/admin-request-handler.cpp index aec75b7901b90f..023d6e59a91a1a 100644 --- a/hphp/runtime/server/admin-request-handler.cpp +++ b/hphp/runtime/server/admin-request-handler.cpp @@ -1013,6 +1013,8 @@ bool AdminRequestHandler::handleCheckRequest(const std::string &cmd, appendStat("fixups", jit::FixupMap::size()); appendStat("units", numLoadedUnits()); appendStat("funcs", Func::nextFuncId()); + appendStat("EvaledUnits", getEvaledUnits()); + appendStat("CreateFuncs", getCreateFuncs()); appendStat("named-entities", NamedEntity::tableSize()); for (auto& pair : NamedEntity::tableStats()) { appendStat(folly::sformat("named-entities-{}", pair.first), pair.second);