/hphp/runtime/vm/jit/prof-data.h
C Header | 268 lines | 176 code | 39 blank | 53 comment | 6 complexity | fd9341934ba9bbb1b4d38f31cd2d51b0 MD5 | raw file
- /*
- +----------------------------------------------------------------------+
- | HipHop for PHP |
- +----------------------------------------------------------------------+
- | Copyright (c) 2010-2015 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. |
- +----------------------------------------------------------------------+
- */
- #ifndef incl_HPHP_PROF_TRANS_DATA_H_
- #define incl_HPHP_PROF_TRANS_DATA_H_
- #include <vector>
- #include <memory>
- #include <unordered_map>
- #include "hphp/util/hash-map-typedefs.h"
- #include "hphp/runtime/vm/func.h"
- #include "hphp/runtime/vm/srckey.h"
- #include "hphp/runtime/vm/jit/types.h"
- #include "hphp/runtime/vm/jit/region-selection.h"
- namespace HPHP { namespace jit {
- //////////////////////////////////////////////////////////////////////
- /**
- * A simple class of a growable number of profiling counters with fixed
- * addresses, suitable for being incremented from the TC.
- */
- template<typename T>
- class ProfCounters {
- public:
- explicit ProfCounters(T initVal)
- : m_initVal(initVal)
- {}
- ProfCounters(const ProfCounters&) = delete;
- ProfCounters& operator=(const ProfCounters&) = delete;
- ~ProfCounters() {
- for (size_t i = 0; i < m_chunks.size(); i++) {
- free(m_chunks[i]);
- }
- }
- T get(uint32_t id) const;
- T* getAddr(uint32_t id);
- private:
- static const uint32_t kCountersPerChunk = 2 * 1024 * 1024 / sizeof(T);
- T m_initVal;
- std::vector<T*> m_chunks;
- };
- typedef std::vector<TCA> PrologueCallersVec;
- /**
- * A record with the callers for each profiling prologue. Besides their main
- * entry points, prologues optionally have a guard entry point that checks that
- * we're in the right function before falling through to the main prologue
- * entry (see MCGenerator::emitFuncGuard). We need to keep track of both kinds
- * of callers for each prologue, so that we can smash them appropriately when
- * regenerating prologues.
- */
- class PrologueCallersRec : private boost::noncopyable {
- public:
- const PrologueCallersVec& mainCallers() const;
- const PrologueCallersVec& guardCallers() const;
- void addMainCaller(TCA caller);
- void addGuardCaller(TCA caller);
- void clearAllCallers();
- void removeMainCaller(TCA caller);
- void removeGuardCaller(TCA caller);
- private:
- PrologueCallersVec m_mainCallers;
- PrologueCallersVec m_guardCallers;
- };
- typedef std::unique_ptr<PrologueCallersRec> PrologueCallersRecPtr;
- struct PrologueID {
- PrologueID(FuncId funcId, int nArgs)
- : m_funcId(funcId)
- , m_nArgs(nArgs)
- { }
- FuncId funcId() const { return m_funcId; }
- int nArgs() const { return m_nArgs; }
- bool operator==(const PrologueID& other) const {
- return m_funcId == other.m_funcId && m_nArgs == other.m_nArgs;
- }
- bool operator<(const PrologueID& other) const {
- return ((m_funcId < other.m_funcId) ||
- (m_funcId == other.m_funcId && m_nArgs < other.m_nArgs));
- }
- struct Hasher {
- size_t operator()(PrologueID pid) const {
- return hash_int64_pair(pid.funcId(), pid.nArgs());
- }
- };
- private:
- FuncId m_funcId;
- int m_nArgs;
- };
- /**
- * A simple wrapper for a map from profiling prologues to TransIDs.
- */
- class PrologueToTransMap {
- public:
- void add(FuncId funcId, int numArgs, TransID transId);
- TransID get(FuncId funcId, int numArgs) const;
- private:
- hphp_hash_map<PrologueID, TransID, PrologueID::Hasher> m_prologueIdToTransId;
- };
- /**
- * A profiling record kept for each translation in JitPGO mode.
- */
- class ProfTransRec {
- public:
- ProfTransRec(TransID id, TransKind kind, Offset lastBcOff, SrcKey sk,
- RegionDescPtr region);
- ProfTransRec(TransID id, TransKind kind, SrcKey sk);
- ProfTransRec(TransID id, TransKind kind, SrcKey sk, int nArgs);
- TransID transId() const;
- TransKind kind() const;
- SrcKey srcKey() const;
- SrcKey lastSrcKey() const;
- Offset startBcOff() const;
- Offset lastBcOff() const;
- Func* func() const;
- FuncId funcId() const;
- RegionDescPtr region() const;
- PrologueCallersRec* prologueCallers() const;
- int prologueArgs() const;
- private:
- TransID m_id; // sequential ID of the associated translation
- TransKind m_kind;
- union {
- Offset m_lastBcOff; // offset of the last bytecode instr
- // for non-prologue translations
- int m_prologueArgs; // for prologues
- };
- RegionDescPtr m_region; // for TransProfile translations
- PrologueCallersRecPtr m_prologueCallers; // for TransProflogue translations
- SrcKey m_sk;
- };
- typedef std::unique_ptr<ProfTransRec> ProfTransRecPtr;
- typedef std::unordered_map<FuncId, TransIDVec> FuncProfTransMap;
- using FuncIdSet = hphp_hash_set<FuncId>;
- /**
- * ProfData encapsulates the profiling data kept by the JIT.
- */
- class ProfData {
- public:
- ProfData();
- ProfData(const ProfData&) = delete;
- ProfData& operator=(const ProfData&) = delete;
- uint32_t numTrans() const;
- TransID curTransID() const;
- bool hasTransRec(TransID id) const;
- SrcKey transSrcKey(TransID id) const;
- SrcKey transLastSrcKey(TransID id) const;
- Offset transStartBcOff(TransID id) const;
- Offset transLastBcOff(TransID id) const;
- PC transLastInstr(TransID id) const;
- Offset transStopBcOff(TransID id) const;
- FuncId transFuncId(TransID id) const;
- Func* transFunc(TransID id) const;
- const TransIDVec& funcProfTransIDs(FuncId funcId) const;
- RegionDescPtr transRegion(TransID id) const;
- TransKind transKind(TransID id) const;
- bool isKindProfile(TransID id) const;
- // The actual counter value, which starts at JitPGOThreshold and goes down.
- int64_t transCounterRaw(TransID id) const;
- // The absolute number of times that a translation executed.
- int64_t transCounter(TransID id) const;
- int64_t* transCounterAddr(TransID id);
- TransID prologueTransId(const Func* func,
- int nArgs) const;
- TransID dvFuncletTransId(const Func* func,
- int nArgs) const;
- PrologueCallersRec* prologueCallers(TransID id) const;
- PrologueCallersRec* prologueCallers(const Func* func, int nArgs) const;
- int prologueArgs(TransID id) const;
- TransID addTransProfile(const RegionDescPtr& region,
- const PostConditions& pconds);
- TransID addTransNonProf(TransKind kind, SrcKey sk);
- TransID addTransPrologue(TransKind kind, SrcKey sk,
- int nArgs);
- PrologueCallersRec* findPrologueCallersRec(const Func* func,
- int nArgs) const;
- void addPrologueMainCaller(const Func* func, int nArgs,
- TCA caller);
- void addPrologueGuardCaller(const Func* func, int nArgs,
- TCA caller);
- bool optimized(SrcKey sk) const;
- bool optimized(FuncId funcId) const;
- void setOptimized(SrcKey sk);
- void setOptimized(FuncId funcId);
- void clearOptimized(SrcKey sk);
- bool profiling(FuncId funcId) const;
- void setProfiling(FuncId funcId);
- void free();
- bool freed() const;
- /*
- * Called when we've finished promoting all the profiling translations for
- * `funcId' to optimized translations. This means we can throw away any
- * allocations we made that we won't need any more for this Func.
- */
- void freeFuncData(FuncId funcId);
- /*
- * Returns whether any block in the given func ends at the supplied offset.
- * This is provided in this format because the region selector wants to
- * terminate profiling translations at block ends (so it doesn't care where
- * blocks start, just where they end).
- */
- bool anyBlockEndsAt(const Func*, Offset offset);
- private:
- uint32_t m_numTrans;
- std::vector<ProfTransRecPtr>
- m_transRecs;
- bool m_freed;
- FuncProfTransMap m_funcProfTrans;
- ProfCounters<int64_t> m_counters;
- SrcKeySet m_optimizedSKs; // set of SrcKeys already optimized
- FuncIdSet m_optimizedFuncs; // set of funcs already optimized
- FuncIdSet m_profilingFuncs; // set of funcs being profiled
- PrologueToTransMap m_prologueDB; // maps (Func,nArgs) => prolog TransID
- PrologueToTransMap m_dvFuncletDB; // maps (Func,nArgs) => DV funclet
- // TransID
- hphp_hash_map<FuncId,hphp_hash_set<Offset>>
- m_blockEndOffsets; // func -> block end offsets
- };
- //////////////////////////////////////////////////////////////////////
- }}
- #endif