hphp/runtime/base/runtime-option.h (1,167 lines of code) (raw):

/* +----------------------------------------------------------------------+ | HipHop for PHP | +----------------------------------------------------------------------+ | Copyright (c) 2010-present 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. | +----------------------------------------------------------------------+ */ #pragma once #include <folly/dynamic.h> #include <folly/experimental/io/FsUtil.h> #include <unordered_map> #include <algorithm> #include <vector> #include <string> #include <map> #include <set> #include <boost/container/flat_set.hpp> #include <memory> #include <sys/stat.h> #include "hphp/runtime/base/config.h" #include "hphp/runtime/base/typed-value.h" #include "hphp/runtime/base/types.h" #include "hphp/util/compilation-flags.h" #include "hphp/util/functional.h" #include "hphp/util/hash-map.h" #include "hphp/util/sha1.h" #include "hphp/hack/src/parser/ffi_bridge/parser_ffi.rs" namespace HPHP { /////////////////////////////////////////////////////////////////////////////// struct AccessLogFileData; struct ErrorLogFileData; struct VirtualHost; struct IpBlockMap; struct SatelliteServerInfo; struct FilesMatch; struct Hdf; struct IniSettingMap; constexpr int kDefaultInitialStaticStringTableSize = 500000; using StringToIntMap = std::unordered_map<std::string, int>; enum class JitSerdesMode { // NB: if changing the encoding here, make sure to update isJitSerializing() // and isJitDeserializing() as needed. // // Bit 0: serialize // Bit 1: deserialize Off = 0x0, Serialize = 0x1, // 00001 SerializeAndExit = 0x5, // 00101 Deserialize = 0x2, // 00010 DeserializeOrFail = 0x6, // 00110 DeserializeOrGenerate = 0xa, // 01010 DeserializeAndDelete = 0xe, // 01110 DeserializeAndExit = 0x12, // 10010 }; enum class RepoMode { Closed = 0, ReadOnly = 1, ReadWrite = 2, }; /* * The bare RepoOptions information that the parser cares about. */ struct RepoOptionsFlags { using StringMap = std::map<std::string, std::string>; using StringVector = std::vector<std::string>; // (Type, HDFName, DV) // (N=no-prefix, P=PHP7, E=Eval, H=Hack.Lang) #define PARSERFLAGS() \ N(StringMap, AliasedNamespaces, {}) \ P(bool, UVS, s_PHP7_master) \ P(bool, LTRAssign, s_PHP7_master) \ H(bool, Hacksperimental, false) \ H(bool, DisableLvalAsAnExpression, false) \ H(bool, AllowNewAttributeSyntax, false) \ H(bool, ConstDefaultFuncArgs, false) \ H(bool, ConstStaticProps, false) \ H(bool, AbstractStaticProps, false) \ H(bool, DisallowFuncPtrsInConstants, false) \ H(bool, AllowUnstableFeatures, false) \ H(bool, EnableXHPClassModifier, true) \ H(bool, DisableXHPElementMangling, true) \ H(bool, EnableEnumClasses, true) \ H(bool, DisallowFunAndClsMethPseudoFuncs, false) \ H(bool, DisallowInstMeth, false) \ /**/ /**/ #define AUTOLOADFLAGS() \ N(std::string, Query, "") \ N(std::string, TrustedDBPath, "") \ N(StringVector, IndexedMethodAttributes, {}) \ /**/ const SHA1& cacheKeySha1() const { return m_sha1; } std::uint32_t getCompilerFlags() const; ParserEnv getParserEnvironment() const; std::uint32_t getFactsFlags() const; std::uint32_t getDeclFlags() const; std::uint32_t getParserFlags() const; std::string getAliasedNamespacesConfig() const; std::string autoloadQuery() const { return Query; } std::string trustedDBPath() const { return TrustedDBPath; } /** * Allowlist consisting of the attributes, marking methods, which Facts * should index */ const StringVector& indexedMethodAttributes() const { return IndexedMethodAttributes; } // Getters for the parser options we pass to HackC for extracting facts bool allowNewAttributeSyntax() const { return AllowNewAttributeSyntax; } bool enableXHPClassModifier() const { return EnableXHPClassModifier; } bool disableXHPElementMangling() const { return DisableXHPElementMangling; } template <typename SerDe> void serde(SerDe& sd) { #define N(t, n, ...) sd(n); #define P(t, n, ...) sd(n); #define H(t, n, ...) sd(n); #define E(t, n, ...) sd(n); PARSERFLAGS() AUTOLOADFLAGS() #undef N #undef P #undef H #undef E sd(m_sha1); } template <typename SerDe> static RepoOptionsFlags makeForSerde(SerDe& sd) { RepoOptionsFlags f; sd(f); return f; } private: RepoOptionsFlags() = default; #define N(t, n, ...) t n; #define P(t, n, ...) t n; #define H(t, n, ...) t n; #define E(t, n, ...) t n; PARSERFLAGS() AUTOLOADFLAGS() #undef N #undef P #undef H #undef E SHA1 m_sha1; friend struct RepoOptions; }; /* * RepoOptionsFlags plus extra state */ struct RepoOptions { RepoOptions(const RepoOptions&) = default; RepoOptions(RepoOptions&&) = default; const RepoOptionsFlags& flags() const { return m_flags; } const std::string& path() const { return m_path; } std::string toJSON() const; const folly::dynamic& toDynamic() const { return m_cachedDynamic; } const struct stat& stat() const { return m_stat; } bool operator==(const RepoOptions& o) const { // If we have hash collisions of unequal RepoOptions, we have // bigger problems. return m_flags.m_sha1 == o.m_flags.m_sha1; } bool operator!=(const RepoOptions& o) const { return !(*this == o); } static const RepoOptions& defaults(); static void setDefaults(const Hdf& hdf, const IniSettingMap& ini); static const RepoOptions& forFile(const char* path); private: RepoOptions() = default; RepoOptions(const char* str, const char* file); void filterNamespaces(); void initDefaults(const Hdf& hdf, const IniSettingMap& ini); void calcCacheKey(); void calcDynamic(); RepoOptionsFlags m_flags; std::string m_path; struct stat m_stat; folly::dynamic m_cachedDynamic; static bool s_init; static RepoOptions s_defaults; }; /** * Configurable options set from command line or configurable file at startup * time. */ struct RuntimeOption { static void Load( IniSettingMap &ini, Hdf& config, const std::vector<std::string>& iniClis = std::vector<std::string>(), const std::vector<std::string>& hdfClis = std::vector<std::string>(), std::vector<std::string>* messages = nullptr, std::string cmd = ""); static bool ServerExecutionMode() { return ServerMode; } static bool GcSamplingEnabled() { return EvalGCSampleRate > 0; } static bool JitSamplingEnabled() { return EvalJit && EvalJitSampleRate > 0; } static void ReadSatelliteInfo( const IniSettingMap& ini, const Hdf& hdf, std::vector<std::shared_ptr<SatelliteServerInfo>>& infos, std::string& xboxPassword, std::set<std::string>& xboxPasswords ); static Optional<folly::fs::path> GetHomePath( const folly::StringPiece user); static std::string GetDefaultUser(); /** * Find a config file corresponding to the given user and parse its * settings into the given ini and hdf objects. * * Return true on success and false on failure. */ static bool ReadPerUserSettings(const folly::fs::path& confFileName, IniSettingMap& ini, Hdf& config); static std::string getTraceOutputFile(); static bool ServerMode; static std::string BuildId; static std::string InstanceId; static std::string DeploymentId; // ID for set of instances deployed at once static int64_t ConfigId; // Queryable to verify a specific config was read static std::string PidFile; static std::map<std::string, ErrorLogFileData> ErrorLogs; static std::string LogFile; static std::string LogFileSymLink; static uint16_t LogFilePeriodMultiplier; static int LogHeaderMangle; static bool AlwaysEscapeLog; static bool AlwaysLogUnhandledExceptions; static bool NoSilencer; static int ErrorUpgradeLevel; // Bitmask of errors to upgrade to E_USER_ERROR static bool CallUserHandlerOnFatals; static bool ThrowExceptionOnBadMethodCall; static bool LogNativeStackOnOOM; static int RuntimeErrorReportingLevel; static int ForceErrorReportingLevel; // Bitmask ORed with the reporting level static std::string ServerUser; // run server under this user account static bool AllowRunAsRoot; // Allow running hhvm as root. static int MaxSerializedStringSize; static int64_t NoticeFrequency; // output 1 out of NoticeFrequency notices static int64_t WarningFrequency; static int RaiseDebuggingFrequency; static int64_t SerializationSizeLimit; static std::string AccessLogDefaultFormat; static std::map<std::string, AccessLogFileData> AccessLogs; static std::string AdminLogFormat; static std::string AdminLogFile; static std::string AdminLogSymLink; static std::map<std::string, AccessLogFileData> RPCLogs; static std::string Host; static std::string DefaultServerNameSuffix; static std::string ServerType; static std::string ServerIP; static std::string ServerFileSocket; static const std::string& GetServerPrimaryIPv4(); static const std::string& GetServerPrimaryIPv6(); static int ServerPort; static int ServerPortFd; static int ServerBacklog; static int ServerConnectionLimit; static int ServerThreadCount; static int ServerQueueCount; static int ServerIOThreadCount; static int ServerHighQueueingThreshold; static bool ServerLegacyBehavior; // Number of worker threads with stack partially on huge pages. static int ServerHugeThreadCount; static int ServerHugeStackKb; static int ServerSchedPolicy; static int ServerSchedPriority; static uint32_t ServerLoopSampleRate; static int ServerWarmupThrottleRequestCount; static int ServerWarmupThrottleThreadCount; static int ServerThreadDropCacheTimeoutSeconds; static int ServerThreadJobLIFOSwitchThreshold; static int ServerThreadJobMaxQueuingMilliSeconds; static bool AlwaysDecodePostDataDefault; static bool ServerThreadDropStack; static bool ServerHttpSafeMode; static bool ServerStatCache; static bool ServerFixPathInfo; static bool ServerAddVaryEncoding; static bool ServerLogSettingsOnStartup; static bool ServerLogReorderProps; static bool ServerForkEnabled; static bool ServerForkLogging; static bool ServerWarmupConcurrently; static bool ServerDedupeWarmupRequests; static int ServerWarmupThreadCount; static int ServerExtendedWarmupThreadCount; static unsigned ServerExtendedWarmupRepeat; static unsigned ServerExtendedWarmupDelaySeconds; static std::vector<std::string> ServerWarmupRequests; static std::vector<std::string> ServerExtendedWarmupRequests; static std::string ServerCleanupRequest; static int ServerInternalWarmupThreads; static boost::container::flat_set<std::string> ServerHighPriorityEndPoints; static bool ServerExitOnBindFail; static int PageletServerThreadCount; static int PageletServerHugeThreadCount; static int PageletServerThreadDropCacheTimeoutSeconds; static int PageletServerQueueLimit; static bool PageletServerThreadDropStack; static int RequestTimeoutSeconds; static int PspTimeoutSeconds; static int PspCpuTimeoutSeconds; static int64_t MaxRequestAgeFactor; static int64_t RequestMemoryMaxBytes; // Approximate upper bound for thread heap that is backed by huge pages. This // doesn't include the first slab colocated with thread stack, if any. static int64_t RequestHugeMaxBytes; static int64_t ImageMemoryMaxBytes; static int ServerGracefulShutdownWait; static bool ServerHarshShutdown; static bool ServerEvilShutdown; static bool ServerKillOnTimeout; static bool Server503OnShutdownAbort; static int ServerPreShutdownWait; static int ServerShutdownListenWait; static int ServerShutdownEOMWait; static int ServerPrepareToStopTimeout; static int ServerPartialPostStatusCode; // If `StopOldServer` is set, we try to stop the old server running // on the local host earlier when we initialize, and we do not start // serving requests until we are confident that the system can give // the new server `ServerRSSNeededMb` resident memory, or till // `OldServerWait` seconds passes after an effort to stop the old // server is made. static bool StopOldServer; static int64_t ServerRSSNeededMb; // Threshold of free memory below which the old server is shutdown immediately // upon a memory pressure check. static int64_t ServerCriticalFreeMb; static int OldServerWait; // The percentage of page caches that can be considered as free (0 - // 100). This is experimental. static int CacheFreeFactor; static std::vector<std::string> ServerNextProtocols; static bool ServerEnableH2C; static int BrotliCompressionEnabled; static int BrotliChunkedCompressionEnabled; static int BrotliCompressionMode; // Base 2 logarithm of the sliding window size. Range is 10-24. static int BrotliCompressionLgWindowSize; static int BrotliCompressionQuality; static int ZstdCompressionEnabled; static int ZstdCompressionLevel; static int ZstdWindowLog; static int ZstdChecksumRate; static int GzipCompressionLevel; static int GzipMaxCompressionLevel; static bool EnableKeepAlive; static bool ExposeHPHP; static bool ExposeXFBServer; static bool ExposeXFBDebug; static std::string XFBDebugSSLKey; static int ConnectionTimeoutSeconds; static bool EnableOutputBuffering; static std::string OutputHandler; static bool ImplicitFlush; static bool EnableEarlyFlush; static bool ForceChunkedEncoding; static int64_t MaxPostSize; static int64_t LowestMaxPostSize; static bool AlwaysPopulateRawPostData; static int64_t UploadMaxFileSize; static std::string UploadTmpDir; static bool EnableFileUploads; static bool EnableUploadProgress; static int64_t MaxFileUploads; static int Rfc1867Freq; static std::string Rfc1867Prefix; static std::string Rfc1867Name; static bool ExpiresActive; static int ExpiresDefault; static std::string DefaultCharsetName; static bool ForceServerNameToHeader; static bool PathDebug; static std::vector<std::shared_ptr<VirtualHost>> VirtualHosts; static std::shared_ptr<IpBlockMap> IpBlocks; static std::vector<std::shared_ptr<SatelliteServerInfo>> SatelliteServerInfos; // If a request has a body over this limit, switch to on-demand reading. // -1 for no limit. static int64_t RequestBodyReadLimit; static bool EnableSSL; static int SSLPort; static int SSLPortFd; static std::string SSLCertificateFile; static std::string SSLCertificateKeyFile; static std::string SSLCertificateDir; static std::string SSLTicketSeedFile; static bool TLSDisableTLS1_2; static std::string TLSClientCipherSpec; static bool EnableSSLWithPlainText; // Level of TLS client auth. Valid values are // 0 => disabled (default) // 1 => optional (verify if client presents a cert) // 2 => required (client must present a valid cert) static int SSLClientAuthLevel; // CA file to verify client cert against. static std::string SSLClientCAFile; // [DEPRECATED] Sampling ratio for client auth logging. // Must be an int within [0, 100]. 0 => disabled; 100 => log all connections. static uint32_t SSLClientAuthLoggingSampleRatio; // Which ACL identity and action to check the client against. static std::string ClientAuthAclIdentity; static std::string ClientAuthAclAction; // If true, terminate connection immediately if a client fails ACL, // otherwise log it and let in. static bool ClientAuthFailClose; // On average, sample X connections per ClientAuthLogSampleBase connections, // where X is ClientAuthSuccessLogSampleRatio for client auth successes, and // ClientAuthFailureLogSampleRatio for client auth failures. Set X to 0 to // disable sampling. // For example, if ClientAuthLogSampleBase = 100, // ClientAuthSuccessLogSampleRatio = 0, and // ClientAuthFailureLogSampleRatio = 50, then no (0/100) client auth successes // and half (50/100) of client auth failures will be logged. static uint32_t ClientAuthLogSampleBase; static uint32_t ClientAuthSuccessLogSampleRatio; static uint32_t ClientAuthFailureLogSampleRatio; static int XboxServerThreadCount; static int XboxServerMaxQueueLength; static int XboxServerInfoMaxRequest; static int XboxServerInfoDuration; static std::string XboxServerInfoReqInitFunc; static std::string XboxServerInfoReqInitDoc; static bool XboxServerInfoAlwaysReset; static bool XboxServerLogInfo; static std::string XboxProcessMessageFunc; static std::string XboxPassword; static std::set<std::string> XboxPasswords; static std::string SourceRoot; static std::vector<std::string> IncludeSearchPaths; /** * Legal root directory expressions in an include expression. For example, * * include_once $PHP_ROOT . '/lib.php'; * * Here, "$PHP_ROOT" is a legal include root. Stores what it resolves to. * * RuntimeOption::IncludeRoots["$PHP_ROOT"] = ""; * RuntimeOption::IncludeRoots["$LIB_ROOT"] = "lib"; */ static std::map<std::string, std::string> IncludeRoots; static std::map<std::string, std::string> AutoloadRoots; static bool AutoloadEnabled; static std::string AutoloadDBPath; static std::string AutoloadDBPerms; static std::string AutoloadDBGroup; static std::string AutoloadLogging; static std::vector<std::string> AutoloadExcludedRepos; static bool AutoloadLoggingAllowPropagation; static bool AutoloadRethrowExceptions; static std::string FileCache; static std::string DefaultDocument; static std::string GlobalDocument; static std::string ErrorDocument404; static bool ForbiddenAs404; static std::string ErrorDocument500; static std::string FatalErrorMessage; static std::string FontPath; static bool EnableStaticContentFromDisk; static bool EnableOnDemandUncompress; static bool EnableStaticContentMMap; static bool Utf8izeReplace; static std::string RequestInitFunction; static std::string RequestInitDocument; static std::string AutoPrependFile; static std::string AutoAppendFile; static bool SafeFileAccess; static std::vector<std::string> AllowedDirectories; static std::set<std::string> AllowedFiles; static hphp_string_imap<std::string> StaticFileExtensions; static hphp_string_imap<std::string> PhpFileExtensions; static std::set<std::string> ForbiddenFileExtensions; static std::set<std::string> StaticFileGenerators; static std::vector<std::shared_ptr<FilesMatch>> FilesMatches; static bool WhitelistExec; static bool WhitelistExecWarningOnly; static std::vector<std::string> AllowedExecCmds; static bool UnserializationWhitelistCheck; static bool UnserializationWhitelistCheckWarningOnly; static int64_t UnserializationBigMapThreshold; static std::string TakeoverFilename; static std::string AdminServerIP; static int AdminServerPort; static int AdminThreadCount; static bool AdminServerEnableSSLWithPlainText; static bool AdminServerStatsNeedPassword; static std::string AdminPassword; static std::set<std::string> AdminPasswords; static std::set<std::string> HashedAdminPasswords; static std::string AdminDumpPath; /* * Options related to reverse proxying. ProxyOriginRaw and ProxyPercentageRaw * may be mutated by background threads and should only be read or written * using the helper functions defined with HttpRequestHandler. */ static std::string ProxyOriginRaw; static int ProxyPercentageRaw; static int ProxyRetry; static bool UseServeURLs; static std::set<std::string> ServeURLs; static bool UseProxyURLs; static std::set<std::string> ProxyURLs; static std::vector<std::string> ProxyPatterns; static bool AlwaysUseRelativePath; static int HttpDefaultTimeout; static int HttpSlowQueryThreshold; static bool NativeStackTrace; static bool ServerErrorMessage; static bool RecordInput; static bool ClearInputOnSuccess; static std::string ProfilerOutputDir; static std::string CoreDumpEmail; static bool CoreDumpReport; static std::string CoreDumpReportDirectory; static std::string StackTraceFilename; static int StackTraceTimeout; static std::string RemoteTraceOutputDir; static std::set<std::string, stdltistr> TraceFunctions; static bool EnableStats; static bool EnableAPCStats; static bool EnableWebStats; static bool EnableMemoryStats; static bool EnableSQLStats; static bool EnableSQLTableStats; static bool EnableNetworkIOStatus; static std::string StatsXSL; static std::string StatsXSLProxy; static uint32_t StatsSlotDuration; static uint32_t StatsMaxSlot; static bool EnableHotProfiler; static int32_t ProfilerTraceBuffer; static double ProfilerTraceExpansion; static int32_t ProfilerMaxTraceBuffer; static int64_t MaxSQLRowCount; static int64_t SocketDefaultTimeout; static bool LockCodeMemory; static int MaxArrayChain; static bool WarnOnCollectionToArray; static bool UseDirectCopy; static bool DisableSmallAllocator; static std::map<std::string, std::string> ServerVariables; static std::map<std::string, std::string> EnvVariables; // The file name that is used by LightProcess to bind the socket // is the following prefix followed by the pid of the hphp process. static std::string LightProcessFilePrefix; static int LightProcessCount; // Eval options static bool EnableHipHopSyntax; static bool EnableXHP; static bool EnableIntrinsicsExtension; static bool CheckSymLink; static bool TrustAutoloaderPath; static bool EnableArgsInBacktraces; static bool EnableZendIniCompat; static bool TimeoutsUseWallTime; static bool CheckFlushOnUserClose; static bool EvalAuthoritativeMode; static int CheckCLIClientCommands; static int CheckIntOverflow; static HackStrictOption StrictArrayFillKeys; static bool LookForTypechecker; static bool AutoTypecheck; static uint32_t EvalInitialStaticStringTableSize; static uint32_t EvalInitialNamedEntityTableSize; static JitSerdesMode EvalJitSerdesMode; static int ProfDataTTLHours; static std::string EvalJitSerdesFile; static std::string ProfDataTag; static bool DumpPreciseProfData; // ENABLED (1) selects PHP7 behavior. static bool PHP7_NoHexNumerics; static bool PHP7_Builtins; static bool PHP7_EngineExceptions; static bool PHP7_Substr; static bool PHP7_DisallowUnsafeCurlUploads; static int64_t HeapSizeMB; static int64_t HeapResetCountBase; static int64_t HeapResetCountMultiple; static int64_t HeapLowWaterMark; static int64_t HeapHighWaterMark; static std::string WatchmanRootSocket; static std::string WatchmanDefaultSocket; // Disables PHP's call_user_func function. // Valid values are 0 => enabled (default), // 1 => warning, 2 => error. static uint64_t DisableCallUserFunc; // Disables PHP's call_user_func_array function. // Valid values are 0 => enabled (default), // 1 => warning, 2 => error. static uint64_t DisableCallUserFuncArray; // Disables PHP's constant function // valid values are 0 => enabled (default) // 1 => warning, 2 => error static uint64_t DisableConstant; // Enables the class-level where constraints // true => allow the feature, false => disable the feature static bool EnableClassLevelWhereClauses; static hphp_string_imap<TypedValue> ConstantFunctions; static const uint32_t kPCREInitialTableSize = 96 * 1024; static std::string ExtensionDir; static std::vector<std::string> Extensions; static std::string DynamicExtensionPath; static std::vector<std::string> DynamicExtensions; static std::vector<std::string> TzdataSearchPaths; #define EVALFLAGS() \ /* F(type, name, defaultVal) */ \ /* \ * Maximum number of elements on the VM execution stack. \ */ \ F(uint64_t, VMStackElms, kEvalVMStackElmsDefault) \ /* \ * Initial space reserved for the global variable environment (in \ * number of global variables). \ */ \ F(uint32_t, VMInitialGlobalTableSize, \ kEvalVMInitialGlobalTableSizeDefault) \ F(bool, Jit, evalJitDefault()) \ F(bool, JitEvaledCode, true) \ F(bool, JitRequireWriteLease, false) \ F(uint64_t, JitRelocationSize, kJitRelocationSizeDefault) \ F(uint64_t, JitMatureSize, 125 << 20) \ F(bool, JitMatureAfterWarmup, false) \ F(double, JitMaturityExponent, 1.) \ F(double, JitMaturityProfWeight, 1.) \ F(bool, JitTimer, kJitTimerDefault) \ F(int, JitConcurrently, 1) \ F(int, JitThreads, 4) \ F(int, JitWorkerThreads, std::max(1, Process::GetCPUCount() / 2)) \ F(int, JitWorkerThreadsForSerdes, 0) \ F(int, JitWorkerArenas, std::max(1, Process::GetCPUCount() / 4)) \ F(bool, JitParallelDeserialize, true) \ F(int, JitLdimmqSpan, 8) \ F(int, JitPrintOptimizedIR, 0) \ F(bool, RecordSubprocessTimes, false) \ F(bool, AllowHhas, false) \ F(bool, GenerateDocComments, true) \ F(bool, DisassemblerDocComments, true) \ F(bool, DisassemblerPropDocComments, true) \ F(bool, LoadFilepathFromUnitCache, false) \ F(bool, FatalOnParserOptionMismatch, true) \ F(bool, WarnOnSkipFrameLookup, true) \ /* \ * 0 - Code coverage cannot be enabled through request param \ * 1 - Code coverage can be enabled through request param \ * 2 - Code coverage enabled \ */ \ F(uint32_t, EnableCodeCoverage, 0) \ F(bool, EnableFuncCoverage, false) \ F(bool, ExtractFactsFromDecls, true) \ /* The number of worker threads to spawn for facts extraction. */ \ F(uint64_t, FactsWorkers, Process::GetCPUCount()) \ /* Whether to log extern compiler performance */ \ F(bool, LogExternCompilerPerf, false) \ /* Whether to write verbose log messages to the error log and include the hhas from failing units in the fatal error messages produced by bad hh_single_compile units. */ \ F(bool, HackCompilerVerboseErrors, true) \ /* Whether the HackC compiler should inherit the compiler config of the HHVM process that launches it. */ \ F(bool, HackCompilerInheritConfig, true) \ /* enable decls in compilation */ \ F(bool, EnableDecl, false) \ /* When using embedded data, extract it to the ExtractPath or the * ExtractFallback. */ \ F(string, EmbeddedDataExtractPath, "/var/run/hhvm_%{type}_%{buildid}") \ F(string, EmbeddedDataFallbackPath, "/tmp/hhvm_%{type}_%{buildid}_XXXXXX") \ /* Whether to trust existing versions of extracted embedded data. */ \ F(bool, EmbeddedDataTrustExtract, true) \ F(bool, LogThreadCreateBacktraces, false) \ F(bool, FailJitPrologs, false) \ F(bool, UseHHBBC, !getenv("HHVM_DISABLE_HHBBC")) \ /* Equivalent to setting the --test-compression HHBBC-only flag. */ \ F(bool, HHBBCTestCompression, false) \ /* Threshold number of units to log to hhvm_whole_program table. systemlib has around 200 units, so use a larger default to avoid logging for unit tests. */ \ F(uint32_t, HHBBCMinUnitsToLog, 1000) \ F(bool, EnablePerRepoOptions, true) \ F(bool, CachePerRepoOptionsPath, true) \ F(bool, LogHackcMemStats, false) \ /* CheckPropTypeHints: 0 - No checks or enforcement of property type hints. 1 - Raises E_WARNING if a property type hint fails. 2 - Raises E_RECOVERABLE_ERROR if regular property type hint fails, raises E_WARNING if soft property type hint fails. If a regular property type hint fails, it's possible for execution to resume normally if the user error handler doesn't throw and returns something other than boolean false. 3 - Same as 2, except if a regular property type hint fails the runtime will not allow execution to resume normally; if the user error handler returns something other than boolean false, the runtime will throw a fatal error. */ \ F(int32_t, CheckPropTypeHints, 1) \ /* Enables enforcing upper-bounds for generic types 1 => warning, 2 => error */ \ F(int32_t, EnforceGenericsUB, 1) \ /* WarnOnTooManyArguments: * 0 -> no warning, 1 -> warning, 2 -> exception */ \ F(uint32_t, WarnOnTooManyArguments, 0) \ /* GetClassBadArgument: * 0 -> no warning, 1 -> warning, 2 -> exception */ \ F(uint32_t, GetClassBadArgument, 0) \ /* WarnOnIncDecInvalidType: * 0 - No restrictions on types that can be incremented or decremented * 1 - Warn when incrementing or decrementing non numeric types * 2 - Throw when incrementing or decrementing non numeric types */ \ F(uint32_t, WarnOnIncDecInvalidType, 0) \ /* WarnOnImplicitCoercionOfEnumValue * This flag exists to control behaviour when implicit coercion is * taking place on an enum value. * 0 - No warning * 1 - Warning * 2 - Do not do implicit coercion */ \ F(uint32_t, WarnOnImplicitCoercionOfEnumValue, 0) \ F(bool, EnableImplicitContext, false) \ F(bool, MoreAccurateMemStats, true) \ F(bool, AllowScopeBinding, false) \ F(bool, TranslateHackC, false) \ F(bool, JitNoGdb, true) \ F(bool, SpinOnCrash, false) \ F(uint32_t, DumpRingBufferOnCrash, 0) \ F(bool, PerfPidMap, true) \ F(bool, PerfPidMapIncludeFilePath, true) \ F(bool, PerfJitDump, false) \ F(string, PerfJitDumpDir, "/tmp") \ F(bool, PerfDataMap, false) \ F(bool, KeepPerfPidMap, false) \ F(uint32_t, ThreadTCMainBufferSize, 6 << 20) \ F(uint32_t, ThreadTCColdBufferSize, 6 << 20) \ F(uint32_t, ThreadTCFrozenBufferSize,4 << 20) \ F(uint32_t, ThreadTCDataBufferSize, 256 << 10) \ F(uint32_t, RDSSize, 64 << 20) \ F(uint32_t, SharedProfileSize, 128 << 20) \ F(uint32_t, HHBCArenaChunkSize, 10 << 20) \ F(bool, ProfileBC, false) \ F(bool, ProfileHeapAcrossRequests, false) \ F(bool, ProfileHWEnable, true) \ F(string, ProfileHWEvents, std::string("")) \ F(bool, ProfileHWExcludeKernel, false) \ F(bool, ProfileHWFastReads, false) \ F(bool, ProfileHWStructLog, false) \ F(int32_t, ProfileHWExportInterval, 30) \ F(string, ReorderProps, reorderPropsDefault()) \ F(bool, ReorderRDS, true) \ F(double, RDSReorderThreshold, 0.0005) \ F(uint32_t, ProfileGlobalsLimit, 200) \ F(double, ProfileGlobalsSlowExitThreshold, 0.98) \ F(bool, JitAlwaysInterpOne, false) \ F(uint32_t, JitNopInterval, 0) \ F(uint32_t, JitMaxTranslations, 10) \ F(uint32_t, JitMaxProfileTranslations, 30) \ F(uint32_t, JitTraceletLiveLocsLimit, 2000) \ F(uint32_t, JitTraceletEagerGuardsLimit, 0) \ F(uint32_t, JitTraceletGuardsLimit, 5) \ F(uint64_t, JitGlobalTranslationLimit, -1) \ F(int64_t, JitMaxRequestTranslationTime, -1) \ F(uint32_t, JitMaxRegionInstrs, 3000) \ F(uint32_t, JitMaxLiveRegionInstrs, 50) \ F(uint32_t, JitMaxAwaitAllUnroll, 8) \ F(bool, JitProfileWarmupRequests, false) \ F(uint32_t, JitProfileRequests, profileRequestsDefault()) \ F(uint32_t, JitProfileBCSize, profileBCSizeDefault()) \ F(uint32_t, JitResetProfCountersRequest, resetProfCountersDefault()) \ F(uint32_t, JitRetranslateAllRequest, retranslateAllRequestDefault()) \ F(uint32_t, JitRetranslateAllSeconds, retranslateAllSecondsDefault()) \ F(bool, JitRerunRetranslateAll, false) \ F(bool, JitBuildOutliningHashes, false) \ F(bool, JitAttemptSuperInlining, false) \ F(bool, JitPGOLayoutSplitHotCold, pgoLayoutSplitHotColdDefault()) \ F(bool, JitPGOVasmBlockCounters, true) \ F(bool, JitPGOVasmBlockCountersOptPrologue, true) \ F(uint32_t, JitPGOVasmBlockCountersMaxOpMismatches, 12) \ F(uint32_t, JitPGOVasmBlockCountersMinEntryValue, \ ServerExecutionMode() ? 200 : 0) \ F(double, JitPGOVasmBlockCountersHotWeightMultiplier, 0) \ F(bool, JitLayoutSeparateZeroWeightBlocks, false) \ F(bool, JitLayoutPrologueSplitHotCold, layoutPrologueSplitHotColdDefault()) \ F(bool, JitLayoutProfileSplitHotCold, true) \ F(uint64_t, JitLayoutMinHotThreshold, 0) \ F(uint64_t, JitLayoutMinColdThreshold, 0) \ F(double, JitLayoutHotThreshold, 0.01) \ F(double, JitLayoutColdThreshold, 0.0005) \ F(int32_t, JitLayoutMainFactor, 1000) \ F(int32_t, JitLayoutColdFactor, 5) \ F(bool, JitLayoutExtTSP, true) \ F(bool, JitLayoutExtTSPForPrologues, false) \ F(double, JitLayoutMaxMergeRatio, 1000000) \ F(bool, JitLayoutPruneCatchArcs, true) \ F(uint32_t, GdbSyncChunks, 128) \ F(bool, JitKeepDbgFiles, false) \ /* despite the unfortunate name, this enables function renaming and * interception in the interpreter as well as the jit, and also * implies all functions may be used with fb_intercept2 */ \ F(bool, JitEnableRenameFunction, EvalJitEnableRenameFunction) \ F(bool, JitUseVtuneAPI, false) \ F(bool, TraceCommandLineRequest, true) \ \ F(bool, JitDisabledByHphpd, false) \ F(bool, JitDisabledByVSDebug, true) \ F(uint32_t, JitWarmupStatusBytes, ((25 << 10) + 1)) \ F(uint32_t, JitWarmupMaxCodeGenRate, 20000) \ F(uint32_t, JitWarmupRateSeconds, 64) \ F(uint32_t, JitWarmupMinFillFactor, 10) \ F(uint32_t, JitWriteLeaseExpiration, 1500) /* in microseconds */ \ F(int, JitRetargetJumps, 1) \ /* Sync VM reg state for all native calls. */ \ F(bool, JitForceVMRegSync, false) \ /* Log the profile used to optimize array-like gets and sets. */ \ F(bool, LogArrayAccessProfile, false) \ /* Log the profile used to target iterator specialization. */ \ F(bool, LogArrayIterProfile, false) \ /* We use PGO to target specialization for "foreach" iterator loops. \ * We specialize if the chosen specialization covers this fraction \ * of profiled loops. If the value is > 1.0, we won't specialize. */ \ F(double, ArrayIterSpecializationRate, 0.99) \ F(bool, HHIRSimplification, true) \ F(bool, HHIRGenOpts, true) \ F(bool, HHIRRefcountOpts, true) \ F(bool, HHIREnableGenTimeInlining, true) \ F(uint32_t, HHIRInliningCostFactorMain, 100) \ F(uint32_t, HHIRInliningCostFactorCold, 32) \ F(uint32_t, HHIRInliningCostFactorFrozen, 10) \ F(uint32_t, HHIRInliningVasmCostLimit, 10500) \ F(uint32_t, HHIRInliningMinVasmCostLimit, 10000) \ F(uint32_t, HHIRInliningMaxVasmCostLimit, 40000) \ F(uint32_t, HHIRAlwaysInlineVasmCostLimit, 4800) \ F(uint32_t, HHIRInliningMaxDepth, 5) \ F(double, HHIRInliningVasmCallerExp, .5) \ F(double, HHIRInliningVasmCalleeExp, .5) \ F(double, HHIRInliningDepthExp, 0) \ F(uint32_t, HHIRInliningMaxReturnDecRefs, 24) \ F(uint32_t, HHIRInliningMaxReturnLocals, 40) \ F(uint32_t, HHIRInliningMaxInitObjProps, 12) \ F(bool, HHIRInliningIgnoreHints, !debug) \ F(bool, HHIRInliningUseStackedCost, false) \ F(bool, HHIRInliningUseLayoutBlocks, false) \ F(bool, HHIRAlwaysInterpIgnoreHint, !debug) \ F(bool, HHIRGenerateAsserts, false) \ F(bool, HHIRDeadCodeElim, true) \ F(bool, HHIRGlobalValueNumbering, true) \ F(bool, HHIRPredictionOpts, true) \ F(bool, HHIROptimizeCheckTypes, true) \ F(bool, HHIRMemoryOpts, true) \ F(bool, AssemblerFoldDefaultValues, true) \ F(uint64_t, AssemblerMaxScalarSize, 2147483648) /* 2GB */ \ F(uint32_t, HHIRLoadElimMaxIters, 10) \ F(uint32_t, HHIRLoadStackTeardownMaxDecrefs, 8) \ F(uint32_t, HHIRLoadThrowMaxDecrefs, 64) \ F(bool, HHIRStorePRE, true) \ F(bool, HHIRSinkDefs, true) \ F(bool, HHIRLowerBespokesPostIRGen, true) \ F(bool, HHIROutlineGenericIncDecRef, true) \ /* How many elements to inline for packed- or mixed-array inits. */ \ F(uint32_t, HHIRMaxInlineInitPackedElements, 8) \ F(uint32_t, HHIRMaxInlineInitMixedElements, 4) \ F(uint32_t, HHIRMaxInlineInitStructElements, 8) \ F(double, HHIROffsetArrayProfileThreshold, 0.85) \ F(double, HHIRCOWArrayProfileThreshold, 0.85) \ F(double, HHIRSmallArrayProfileThreshold, 0.8) \ F(double, HHIRMissingArrayProfileThreshold, 0.8) \ F(double, HHIRExitArrayProfileThreshold, 0.98) \ F(double, HHIROffsetExitArrayProfileThreshold, 0.98) \ F(double, HHIRIsTypeStructProfileThreshold, 0.95) \ /* Register allocation flags */ \ F(bool, HHIREnablePreColoring, true) \ F(bool, HHIREnableCoalescing, true) \ F(bool, HHIRAllocSIMDRegs, true) \ /* Region compiler flags */ \ F(string, JitRegionSelector, regionSelectorDefault()) \ F(bool, JitPGO, pgoDefault()) \ F(string, JitPGORegionSelector, "hotcfg") \ F(uint64_t, JitPGOThreshold, pgoThresholdDefault()) \ F(bool, JitPGOOnly, false) \ F(bool, JitPGOUsePostConditions, true) \ F(bool, JitPGOUseAddrCountedCheck, false) \ F(uint32_t, JitPGOUnlikelyIncRefCountedPercent, 2) \ F(uint32_t, JitPGOUnlikelyIncRefIncrementPercent, 5) \ F(uint32_t, JitPGOUnlikelyDecRefReleasePercent, 5) \ F(uint32_t, JitPGOUnlikelyDecRefCountedPercent, 2) \ F(uint32_t, JitPGOUnlikelyDecRefPersistPercent, 5) \ F(uint32_t, JitPGOUnlikelyDecRefSurvivePercent, 5) \ F(uint32_t, JitPGOUnlikelyDecRefDecrementPercent, 5) \ F(double, JitPGODecRefNZReleasePercentCOW, \ ServerExecutionMode() ? 0.5 : 0) \ F(double, JitPGODecRefNZReleasePercent, \ ServerExecutionMode() ? 5 : 0) \ F(double, JitPGODecRefNopDecPercentCOW, \ ServerExecutionMode() ? 0.5 : 0) \ F(double, JitPGODecRefNopDecPercent, ServerExecutionMode() ? 5 : 0) \ F(bool, JitPGOArrayGetStress, false) \ F(double, JitPGOMinBlockCountPercent, 0.25) \ F(double, JitPGOMinArcProbability, 0.0) \ F(uint32_t, JitPGOMaxFuncSizeDupBody, 80) \ F(uint32_t, JitPGORelaxPercent, 100) \ F(double, JitPGOCalledFuncCheckThreshold, 50) \ F(double, JitPGOCalledFuncExitThreshold, 99.9) \ F(bool, JitPGODumpCallGraph, false) \ F(bool, JitPGOOptCodeCallGraph, true) \ F(bool, JitPGORacyProfiling, false) \ F(bool, JitPGOHFSortPlus, false) \ F(uint32_t, JitLiveThreshold, ServerExecutionMode() ? 1000 : 0) \ F(uint32_t, JitProfileThreshold, ServerExecutionMode() ? 200 : 0) \ F(uint32_t, JitSrcKeyThreshold, 0) \ F(uint32_t, JitMaxLiveMainUsage, 96 * 1024 * 1024) \ F(uint64_t, FuncCountHint, 10000) \ F(uint64_t, PGOFuncCountHint, 1000) \ F(bool, RegionRelaxGuards, true) \ /* DumpBytecode =1 dumps user php, =2 dumps systemlib & user php */ \ F(int32_t, DumpBytecode, 0) \ /* DumpHhas =1 dumps user php, =2 dumps systemlib & user php */ \ F(int32_t, DumpHhas, 0) \ F(string, DumpHhasToFile, "") \ F(bool, DumpTC, false) \ F(string, DumpTCPath, "/tmp") \ F(bool, DumpTCAnchors, false) \ F(uint32_t, DumpIR, 0) \ F(uint32_t, DumpIRJson, 0) \ F(bool, DumpTCAnnotationsForAllTrans,debug) \ /* DumpInlDecision 0=none ; 1=refuses ; 2=refuses+accepts */ \ F(uint32_t, DumpInlDecision, 0) \ F(uint32_t, DumpRegion, 0) \ F(bool, DumpCallTargets, false) \ F(bool, DumpLayoutCFG, false) \ F(bool, DumpVBC, false) \ F(bool, DumpArrAccProf, false) \ F(bool, DumpAst, false) \ F(bool, DumpTargetProfiles, false) \ F(bool, MapTgtCacheHuge, false) \ F(bool, NewTHPHotText, false) \ F(bool, FileBackedColdArena, useFileBackedArenaDefault()) \ F(string, ColdArenaFileDir, "/tmp") \ F(uint32_t, MaxHotTextHugePages, hotTextHugePagesDefault()) \ F(uint32_t, MaxLowMemHugePages, hugePagesSoundNice() ? 8 : 0) \ F(uint32_t, MaxHighArenaHugePages, 0) \ F(uint32_t, Num1GPagesForSlabs, 0) \ F(uint32_t, Num2MPagesForSlabs, 0) \ F(uint32_t, Num1GPagesForReqHeap, 0) \ F(uint32_t, Num2MPagesForReqHeap, 0) \ F(uint32_t, NumReservedSlabs, 0) \ F(uint32_t, Num1GPagesForA0, 0) \ F(uint32_t, Num2MPagesForA0, 0) \ F(bool, BigAllocUseLocalArena, true) \ F(bool, JsonParserUseLocalArena, true) \ F(bool, XmlParserUseLocalArena, true) \ F(bool, LowStaticArrays, true) \ F(bool, RecycleAProf, true) \ F(int64_t, HeapPurgeWindowSize, 5 * 1000000) \ F(uint64_t, HeapPurgeThreshold, 128 * 1024 * 1024) \ /* GC Options: See heap-collect.cpp for more details */ \ F(bool, EagerGC, eagerGcDefault()) \ F(bool, FilterGCPoints, true) \ F(bool, Quarantine, eagerGcDefault()) \ F(bool, HeapAllocSampleNativeStack, false) \ F(bool, LogKilledRequests, true) \ F(uint32_t, GCSampleRate, 0) \ F(uint32_t, HeapAllocSampleRequests, 0) \ F(uint32_t, HeapAllocSampleBytes, 256 * 1024) \ F(uint32_t, SlabAllocAlign, 64) \ F(uint32_t, MemTrackStart, 3500) \ F(uint32_t, MemTrackEnd, 3700) \ F(int64_t, GCMinTrigger, 64L<<20) \ F(double, GCTriggerPct, 0.5) \ F(bool, TwoPhaseGC, false) \ F(bool, EnableGC, enableGcDefault()) \ /* End of GC Options */ \ F(bool, Verify, getenv("HHVM_VERIFY")) \ F(bool, VerifyOnly, false) \ F(bool, FatalOnVerifyError, !RepoAuthoritative) \ F(bool, AbortBuildOnVerifyError, true) \ F(bool, AbortBuildOnCompilerError, true) \ F(uint32_t, StaticContentsLogRate, 100) \ F(uint32_t, LogUnitLoadRate, 0) \ F(uint32_t, MaxDeferredErrors, 50) \ F(bool, JitAlignMacroFusionPairs, alignMacroFusionPairs()) \ F(bool, JitAlignUniqueStubs, true) \ F(uint32_t, SerDesSampleRate, 0) \ F(bool, JitSerdesModeForceOff, false) \ F(bool, JitDesUnitPreload, false) \ F(std::set<std::string>, JitSerdesDebugFunctions, {}) \ F(uint32_t, JitSerializeOptProfSeconds, ServerExecutionMode() ? 300 : 0)\ F(uint32_t, JitSerializeOptProfRequests, 0) \ F(bool, JitSerializeOptProfRestart, true) \ F(int, SimpleJsonMaxLength, 2 << 20) \ F(uint32_t, JitSampleRate, 0) \ F(uint32_t, TraceServerRequestRate, 0) \ /* Tracing Options */ \ /* Base tracing sample rate for all requests */ \ F(uint32_t, TracingSampleRate, 0) \ /* Tracing sample rate for first N requests */ \ F(uint32_t, TracingPerRequestCount, 0) \ F(uint32_t, TracingPerRequestSampleRate, 0) \ /* Tracing sample rate for first N requests per URL */ \ F(uint32_t, TracingFirstRequestsCount, 0) \ F(uint32_t, TracingFirstRequestsSampleRate, 0) \ /* Empty string disables any Artillery tracing */ \ F(std::string, ArtilleryTracePolicy, "") \ /* Opaque tag to add to each trace. Useful for aggregation */ \ F(std::string, TracingTagId, "") \ /* Log the sizes and metadata for all translations in the TC broken * down by function and inclusive/exclusive size for inlined regions. * When set to "" TC size data will be sampled on a per function basis * as determined by JitSampleRate. When set to a non-empty string all * translations will be logged, and run_key column will be logged with * the value of this option. */ \ F(string, JitLogAllInlineRegions, "") \ F(bool, JitProfileGuardTypes, false) \ F(uint32_t, JitFilterLease, 1) \ F(uint32_t, PCRETableSize, kPCREInitialTableSize) \ F(uint64_t, PCREExpireInterval, 2 * 60 * 60) \ F(string, PCRECacheType, std::string("static")) \ F(bool, EnableCompactBacktrace, true) \ F(bool, EnableNuma, (numa_num_nodes > 1) && ServerExecutionMode()) \ /* Use 1G pages for jemalloc metadata. */ \ F(bool, EnableArenaMetadata1GPage, false) \ /* Use 1G pages for jemalloc metadata (NUMA arenas if applicable). */ \ F(bool, EnableNumaArenaMetadata1GPage, false) \ /* Reserved space on 1G pages for jemalloc metadata (arena0). */ \ F(uint64_t, ArenaMetadataReservedSize, 216 << 20) \ F(bool, EnableCallBuiltin, true) \ F(bool, EnableReusableTC, reuseTCDefault()) \ F(bool, LogServerRestartStats, false) \ /* Extra bytes added to each area (Hot/Cold/Frozen) of a translation. \ * If we don't end up using a reusable TC, we'll drop the padding. */ \ F(uint32_t, ReusableTCPadding, 128) \ F(int64_t, StressUnitCacheFreq, 0) \ /* Perf warning sampling rates. The SelectHotCFG warning is noisy. */ \ F(int64_t, PerfWarningSampleRate, 1) \ F(int64_t, SelectHotCFGSampleRate, 100) \ F(int64_t, FunctionCallSampleRate, 0) \ F(double, InitialLoadFactor, 1.0) \ /* Controls emitting checks for bespoke arrays and using logging \ * arrays at runtime. \ * \ * 0 - Disable bespokes. We assume that all array-likes have their \ * standard (aka "vanilla") layouts. \ * 1 - Test bespokes. We emit checks for vanilla layouts and produce \ * logging arrays based on the request ID. If rid % 2 == 1, then \ * a logging array is generated. \ * 2 - Production bespokes. We emit checks as in (1), and produce \ * logging arrays based on per creation site sampling with the \ * sample rate specified by EmitLoggingArraySampleRate. If the \ * sample rate is 0, logging arrays are never constructed. \ * Logging arrays are only created before RTA has begun. */ \ F(int32_t, BespokeArrayLikeMode, 2) \ F(uint64_t, BespokeEscalationSampleRate, 0) \ F(uint64_t, EmitLoggingArraySampleRate, 17) \ F(string, ExportLoggingArrayDataPath, "") \ /* Should we use structs? If so, how big can they get? Due to how we \ * represent structs, we can't make any with more than 255 keys. */ \ F(bool, EmitBespokeStructDicts, true) \ F(uint8_t, BespokeStructDictMaxNumKeys, 245) \ F(double, BespokeStructDictKeyCoverageThreshold, 95.0) \ F(uint8_t, BespokeStructDictMinKeys, 4) \ F(double, BespokeStructDictMaxSizeRatio, 256.0) \ /* What is the maximum number of keys to track in key order \ * profiles? */ \ F(uint64_t, BespokeMaxTrackedKeys, 245) \ F(bool, EmitAPCBespokeArrays, true) \ /* Should we use monotypes? */ \ F(bool, EmitBespokeMonotypes, false) \ F(int64_t, ObjProfMaxNesting, 5000) \ /* Choice of layout selection algorithms: \ * \ * 0 - Default layout selection algorithm based on profiling. \ * May use a mix of vanilla and bespoke array-likes. \ * 1 - Specialize all sources and sinks on vanilla layouts. \ * 2 - Specialize sources on vanilla, but sinks on top. */ \ F(int32_t, BespokeArraySpecializationMode, 0) \ /* We will use specialized layouts for a given array if they cover \ * the given percent of operations logged during profiling. \ * \ * We can generate code for a bespoke sink in three ways: \ * 1. We can do "top codegen" that handles any array layout. \ * 2. We can specialize on a layout and fall back to top codegen. \ * 3. We can specialize on a layout and side-exit on guard failure. \ * \ * We use a couple heuristics to choose between these options. If we \ * see one layout that covers `SideExitThreshold` percent cases, and \ * we saw at most `SideExitMaxSources` sources reach this sink, with \ * at least `SideExitMinSampleCount` samples each, we'll side-exit. \ * \ * Else, if one layout covers `SpecializationThreshold` percent, we \ * will specialize and fall back to top codegen. Otherwise, we'll do \ * top codegen. */ \ F(double, BespokeArraySourceSpecializationThreshold, 95.0) \ F(double, BespokeArraySinkSpecializationThreshold, 95.0) \ F(double, BespokeArraySinkSideExitThreshold, 95.0) \ F(uint64_t, BespokeArraySinkSideExitMaxSources, 64) \ F(uint64_t, BespokeArraySinkSideExitMinSampleCount, 4) \ F(bool, HackArrCompatSerializeNotices, false) \ /* When this flag is on, var_export outputs d/varrays. */ \ F(bool, HackArrDVArrVarExport, false) \ /* Raise a notice when the result of appending to a dict or darray \ * is affected by removing keys from that array-like. */ \ F(bool, DictDArrayAppendNotices, true) \ /* Warn if is expression are used with type aliases that cannot be | * resolved */ \ F(bool, IsExprEnableUnresolvedWarning, false) \ /* Raise a notice if a Class type is passed to is_string */ \ F(bool, ClassIsStringNotices, false) \ /* Raise a notice if a Class type is passed to function that expects a string */ \ F(bool, ClassStringHintNotices, false) \ /* Raise a notice if a Class type is used as a memo key */ \ F(bool, ClassMemoNotices, false) \ /* When this options is on, classname type-hints accepts classes */ \ F(bool, ClassPassesClassname, true) \ /* Raise notice if a Class type is passed to a classname type-hint */ \ F(bool, ClassnameNotices, false) \ /* Raise a notice if a ClsMeth type is passed to is_vec/is_array */ \ F(bool, IsVecNotices, false) \ /* Raise a notice if a ClsMeth type is passed to a function that * expects a vec/varray */ \ F(bool, VecHintNotices, false) \ /* Switches on miscellaneous junk. */ \ F(bool, NoticeOnCreateDynamicProp, false) \ F(bool, NoticeOnReadDynamicProp, false) \ F(bool, NoticeOnImplicitInvokeToString, false) \ F(bool, FatalOnConvertObjectToString, false) \ F(bool, NoticeOnBuiltinDynamicCalls, false) \ /* Raise warning when class pointers are used as strings. */ \ F(bool, RaiseClassConversionWarning, false) \ F(bool, EmitClsMethPointers, true) \ F(bool, FoldLazyClassKeys, true) \ /* EmitClassPointers: * 0 => convert Foo::class to string "Foo" * 1 => convert Foo::class to class pointer * 2 => convert Foo::class to lazy class */ \ F(int32_t, EmitClassPointers, 2) \ /* When this flag is on, var_dump for * classes and lazy classes outputs string(...). */ \ F(bool, ClassAsStringVarDump, true) \ /* When this flag is on, var_export for * classes and lazy classes outputs a string. */ \ F(bool, ClassAsStringVarExport, false) \ /* When this flag is on, gettype for * classes and lazy classes outputs string. */ \ F(bool, ClassAsStringGetType, true) \ /* Raise warning when strings are used as classes. */ \ F(bool, RaiseStrToClsConversionWarning, false) \ F(bool, EmitMethCallerFuncPointers, false) \ /* trigger E_USER_WARNING error when getClassName()/getMethodName() * is used on __SystemLib\MethCallerHelper */ \ F(bool, NoticeOnMethCallerHelperUse, false) \ /* \ * Control dynamic calls to functions and dynamic constructs of \ * classes which haven't opted into being called that way. \ * \ * 0 - Do nothing \ * 1 - Warn if meth_caller is apc serialized \ * 2 - Throw exception if meth_caller is apc serialized \ */ \ F(int32_t, ForbidMethCallerAPCSerialize, 0) \ F(int32_t, ForbidMethCallerHelperSerialize, 0) \ /* \ * When Eval.NoticeOnMethCallerHelperIsObject is set calling is_object\ * on instance of MethCallerHelper will raise notices. \ * \ * In Repo.Authoritative mode, Eval.NoticeOnMethCallerHelperIsObject \ * can only be set if the repo was built with the option \ * Eval.BuildMayNoticeOnMethCallerHelperIsObject set to true. \ */ \ F(bool, BuildMayNoticeOnMethCallerHelperIsObject, false) \ F(bool, NoticeOnMethCallerHelperIsObject, false) \ F(bool, NoticeOnCollectionToBool, false) \ F(bool, NoticeOnSimpleXMLBehavior, false) \ /* \ * Control dynamic calls to functions and dynamic constructs of \ * classes which haven't opted into being called that way. \ * \ * 0 - Do nothing \ * 1 - Warn if target is not annotated \ * 2 - Throw exception if target is not annotated; warn if dynamic \ * callsite is using a raw string or array (depending on \ * ForbidDynamicCallsWithAttr setting) \ * 3 - Throw exception \ */ \ F(int32_t, ForbidDynamicCallsToFunc, 0) \ F(int32_t, ForbidDynamicCallsToClsMeth, 0) \ F(int32_t, ForbidDynamicCallsToInstMeth, 0) \ F(int32_t, ForbidDynamicConstructs, 0) \ /* \ * Keep logging dynamic calls according to options above even if \ * __DynamicallyCallable attribute is present at declaration. \ */ \ F(bool, ForbidDynamicCallsWithAttr, true) \ /* Toggles logging for expressions of type $var::name() */ \ F(bool, LogKnownMethodsAsDynamicCalls, true) \ /* \ * Don't allow unserializing to __PHP_Incomplete_Class \ * 0 - Nothing \ * 1 - Warn \ * 2 - Throw exception \ */ \ F(int32_t, ForbidUnserializeIncompleteClass, 0) \ /* \ * Map from coeffect name to enforcement level \ * e.g. {'pure' => 2, 'rx' => 1} \ */ \ F(StringToIntMap, CoeffectEnforcementLevels, coeffectEnforcementLevelsDefaults()) \ F(uint64_t, CoeffectViolationWarningMax, std::numeric_limits<uint64_t>::max()) \ /* \ * Enforce top level and method level internal keyword \ * 0 - Nothing \ * 1 - Warn \ * 2 - Throw exception \ */ \ F(uint64_t, EnforceModules, 0) \ /* \ * Controls behavior on reflection to default value expressions \ * that throw during evaluation \ * 0 - Nothing \ * 1 - Warn and retain current behavior \ * 2 - Return null for parameter value \ */ \ F(int32_t, FixDefaultArgReflection, 1) \ F(int32_t, ServerOOMAdj, 0) \ F(std::string, PreludePath, "") \ F(uint32_t, NonSharedInstanceMemoCaches, 10) \ F(bool, UseGraphColor, true) \ F(std::vector<std::string>, IniGetHide, std::vector<std::string>()) \ F(std::string, UseRemoteUnixServer, "no") \ F(std::string, UnixServerPath, "") \ F(uint32_t, UnixServerWorkers, Process::GetCPUCount()) \ F(bool, UnixServerQuarantineApc, false) \ F(bool, UnixServerQuarantineUnits, false) \ F(bool, UnixServerVerifyExeAccess, false) \ F(bool, UnixServerFailWhenBusy, false) \ F(std::vector<std::string>, UnixServerAllowedUsers, \ std::vector<std::string>()) \ F(std::vector<std::string>, UnixServerAllowedGroups, \ std::vector<std::string>()) \ /* Options for testing */ \ F(bool, TrashFillOnRequestExit, false) \ /****************** \ | ARM Options. | \ *****************/ \ F(bool, JitArmLse, armLseDefault()) \ /******************** \ | Profiling flags. | \ ********************/ \ /* Whether to maintain the address-to-VM-object mapping. */ \ F(bool, EnableReverseDataMap, true) \ /* Turn on perf-mem-event sampling roughly every this many requests. \ * To maintain the same overall sampling rate, the ratio between the \ * request and sample frequencies should be kept constant. */ \ F(uint32_t, PerfMemEventRequestFreq, 0) \ /* Sample this many memory instructions per second. This should be \ * kept low to avoid the risk of collecting a sample while we're \ * processing a previous sample. */ \ F(uint32_t, PerfMemEventSampleFreq, 80) \ /* Sampling frequency for TC branch profiling. */ \ F(uint32_t, ProfBranchSampleFreq, 0) \ F(bool, UseXedAssembler, false) \ /* Record the first N units loaded via StructuredLog::log() */ \ F(uint64_t, RecordFirstUnits, 0) \ /* More aggresively reuse already compiled units based on SHA1 */ \ F(bool, CheckUnitSHA1, true) \ F(bool, ReuseUnitsByHash, false) \ F(bool, UseEdenFS, true) \ /* Arbitrary string to force different unit-cache hashes */ \ F(std::string, UnitCacheBreaker, "") \ /* When dynamic_fun is called on a function not marked as __DynamicallyCallable: 0 - do nothing 1 - raise a warning 2 - throw */ \ F(uint64_t, DynamicFunLevel, 1) \ /* When dynamic_class_meth is called on a method not marked as __DynamicallyCallable: 0 - do nothing 1 - raise a warning 2 - throw */ \ F(uint64_t, DynamicClsMethLevel, 1) \ /* When dynamic_meth_caller is called on a static method or a method not marked as __DynamicallyCallable: 0 - do nothing 1 - raise a warning 2 - throw */ \ F(uint64_t, DynamicMethCallerLevel, 1) \ F(bool, APCSerializeFuncs, true) \ F(bool, APCSerializeClsMeth, true) \ /* When set: * - `is_array` becomes equivalent to `is_any_array` or * `isTvArrayLike` instead of being a strict PHP array check. */ \ F(bool, EnablePerFileCoverage, false) \ F(bool, LogOnIsArrayFunction, false) \ /* Unit prefetching options */ \ F(uint32_t, UnitPrefetcherMaxThreads, 0) \ F(uint32_t, UnitPrefetcherMinThreads, 0) \ F(uint32_t, UnitPrefetcherIdleThreadTimeoutSecs, 60) \ /* Delete any Unit not used in last N seconds */ \ F(uint32_t, IdleUnitTimeoutSecs, 0) \ /* Don't reap total Units below threshold */ \ F(uint32_t, IdleUnitMinThreshold, 0) \ /* 0 nothing, 1 notice, 2 error */ \ F(int32_t, NoticeOnCoerceForStrConcat, 0) \ /* 0 nothing, 1 notice, 2 error */ \ F(int32_t, NoticeOnCoerceForStrConcat2, 0) \ F(string, TaoMigrationOverride, std::string("")) \ F(string, SRRouteMigrationOverride, std::string("")) \ F(int32_t, SampleRequestTearing, 0) \ F(int32_t, RequestTearingSkewMicros, 1500) \ F(bool, SampleRequestTearingForce, true) \ F(bool, EnableAbstractContextConstants, true) \ F(bool, TypeconstAbstractDefaultReflectionIsAbstract, false) \ F(bool, AbstractContextConstantUninitAccess, false) \ F(bool, TraitConstantInterfaceBehavior, false) \ /* 0 nothing, 1 notice, 2 error */ \ F(uint32_t, ThrowOnIterationOverObjects, 0) \ F(string, TaintConfigurationPath, std::string("")) \ F(string, TaintConfigurationJson, std::string("")) \ F(string, TaintOutputDirectory, std::string("")) \ F(bool, TaintLogRequestURLs, false) \ F(bool, DiamondTraitMethods, false) \ F(uint32_t, HHIRSpecializedDestructorThreshold, 80) \ /* */ private: using string = std::string; // Custom settings. This should be accessed via the GetServerCustomSetting // APIs. static std::map<std::string, std::string> CustomSettings; public: #define F(type, name, unused) \ static type Eval ## name; EVALFLAGS() #undef F static bool RecordCodeCoverage; static std::string CodeCoverageOutputFile; // Repo (hhvm bytecode repository) options static std::string RepoPath; static int64_t RepoLocalReadaheadRate; static bool RepoLocalReadaheadConcurrent; static bool RepoLitstrLazyLoad; static bool RepoDebugInfo; static bool RepoAuthoritative; // These are (functionally) unused static RepoMode RepoLocalMode; static std::string RepoLocalPath; static RepoMode RepoCentralMode; static std::string RepoCentralPath; static int32_t RepoCentralFileMode; static std::string RepoCentralFileUser; static std::string RepoCentralFileGroup; static bool RepoAllowFallbackPath; static std::string RepoJournal; static bool RepoCommit; static uint32_t RepoBusyTimeoutMS; // pprof/hhprof options static bool HHProfEnabled; static bool HHProfActive; static bool HHProfAccum; static bool HHProfRequest; static bool TrackPerUnitMemory; // Sandbox options static bool SandboxMode; static std::string SandboxPattern; static std::string SandboxHome; static std::string SandboxFallback; static std::string SandboxConfFile; static std::map<std::string, std::string> SandboxServerVariables; static bool SandboxFromCommonRoot; static std::string SandboxDirectoriesRoot; static std::string SandboxLogsRoot; static std::string SandboxDefaultUserFile; static std::string SandboxHostAlias; // Debugger options static bool EnableHphpdDebugger; static bool EnableVSDebugger; static int VSDebuggerListenPort; static std::string VSDebuggerDomainSocketPath; static bool VSDebuggerNoWait; static bool EnableDebuggerColor; static bool EnableDebuggerPrompt; static bool EnableDebuggerServer; static bool EnableDebuggerUsageLog; static bool DebuggerDisableIPv6; static std::string DebuggerServerIP; static int DebuggerServerPort; static std::string DebuggerDefaultSandboxPath; static std::string DebuggerStartupDocument; static int DebuggerSignalTimeout; static std::string DebuggerAuthTokenScriptBin; static std::string DebuggerSessionAuthScriptBin; // Mail options static std::string SendmailPath; static std::string MailForceExtraParameters; // preg stack depth and debug support options static int64_t PregBacktraceLimit; static int64_t PregRecursionLimit; static bool EnablePregErrorLog; // SimpleXML options static bool SimpleXMLEmptyNamespaceMatchesAll; #ifdef FACEBOOK // fb303 server static bool EnableFb303Server; static int Fb303ServerPort; static std::string Fb303ServerIP; static int Fb303ServerThreadStackSizeMb; static int Fb303ServerWorkerThreads; static int Fb303ServerPoolThreads; #endif // Xenon options static double XenonPeriodSeconds; static uint32_t XenonRequestFreq; static bool XenonForceAlwaysOn; // Strobelight options static bool StrobelightEnabled; static bool SetProfileNullThisObject; static bool ApplySecondaryQueuePenalty; }; static_assert(sizeof(RuntimeOption) == 1, "no instance variables"); using RO = RuntimeOption; inline bool isJitDeserializing() { auto const m = RuntimeOption::EvalJitSerdesMode; return static_cast<std::underlying_type<JitSerdesMode>::type>(m) & 0x2; } inline bool isJitSerializing() { auto const m = RuntimeOption::EvalJitSerdesMode; return static_cast<std::underlying_type<JitSerdesMode>::type>(m) & 0x1; } inline bool unitPrefetchingEnabled() { return RO::EvalUnitPrefetcherMaxThreads > 0; } inline StringToIntMap coeffectEnforcementLevelsDefaults() { #ifdef FACEBOOK return {{"zoned", 2}}; #else return {}; #endif } uintptr_t lowArenaMinAddr(); /////////////////////////////////////////////////////////////////////////////// }