PageRenderTime 26ms CodeModel.GetById 8ms RepoModel.GetById 1ms app.codeStats 0ms

/hphp/runtime/vm/jit/prof-data.h

https://gitlab.com/alvinahmadov2/hhvm
C Header | 268 lines | 176 code | 39 blank | 53 comment | 6 complexity | fd9341934ba9bbb1b4d38f31cd2d51b0 MD5 | raw file
  1. /*
  2. +----------------------------------------------------------------------+
  3. | HipHop for PHP |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 2010-2015 Facebook, Inc. (http://www.facebook.com) |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. */
  16. #ifndef incl_HPHP_PROF_TRANS_DATA_H_
  17. #define incl_HPHP_PROF_TRANS_DATA_H_
  18. #include <vector>
  19. #include <memory>
  20. #include <unordered_map>
  21. #include "hphp/util/hash-map-typedefs.h"
  22. #include "hphp/runtime/vm/func.h"
  23. #include "hphp/runtime/vm/srckey.h"
  24. #include "hphp/runtime/vm/jit/types.h"
  25. #include "hphp/runtime/vm/jit/region-selection.h"
  26. namespace HPHP { namespace jit {
  27. //////////////////////////////////////////////////////////////////////
  28. /**
  29. * A simple class of a growable number of profiling counters with fixed
  30. * addresses, suitable for being incremented from the TC.
  31. */
  32. template<typename T>
  33. class ProfCounters {
  34. public:
  35. explicit ProfCounters(T initVal)
  36. : m_initVal(initVal)
  37. {}
  38. ProfCounters(const ProfCounters&) = delete;
  39. ProfCounters& operator=(const ProfCounters&) = delete;
  40. ~ProfCounters() {
  41. for (size_t i = 0; i < m_chunks.size(); i++) {
  42. free(m_chunks[i]);
  43. }
  44. }
  45. T get(uint32_t id) const;
  46. T* getAddr(uint32_t id);
  47. private:
  48. static const uint32_t kCountersPerChunk = 2 * 1024 * 1024 / sizeof(T);
  49. T m_initVal;
  50. std::vector<T*> m_chunks;
  51. };
  52. typedef std::vector<TCA> PrologueCallersVec;
  53. /**
  54. * A record with the callers for each profiling prologue. Besides their main
  55. * entry points, prologues optionally have a guard entry point that checks that
  56. * we're in the right function before falling through to the main prologue
  57. * entry (see MCGenerator::emitFuncGuard). We need to keep track of both kinds
  58. * of callers for each prologue, so that we can smash them appropriately when
  59. * regenerating prologues.
  60. */
  61. class PrologueCallersRec : private boost::noncopyable {
  62. public:
  63. const PrologueCallersVec& mainCallers() const;
  64. const PrologueCallersVec& guardCallers() const;
  65. void addMainCaller(TCA caller);
  66. void addGuardCaller(TCA caller);
  67. void clearAllCallers();
  68. void removeMainCaller(TCA caller);
  69. void removeGuardCaller(TCA caller);
  70. private:
  71. PrologueCallersVec m_mainCallers;
  72. PrologueCallersVec m_guardCallers;
  73. };
  74. typedef std::unique_ptr<PrologueCallersRec> PrologueCallersRecPtr;
  75. struct PrologueID {
  76. PrologueID(FuncId funcId, int nArgs)
  77. : m_funcId(funcId)
  78. , m_nArgs(nArgs)
  79. { }
  80. FuncId funcId() const { return m_funcId; }
  81. int nArgs() const { return m_nArgs; }
  82. bool operator==(const PrologueID& other) const {
  83. return m_funcId == other.m_funcId && m_nArgs == other.m_nArgs;
  84. }
  85. bool operator<(const PrologueID& other) const {
  86. return ((m_funcId < other.m_funcId) ||
  87. (m_funcId == other.m_funcId && m_nArgs < other.m_nArgs));
  88. }
  89. struct Hasher {
  90. size_t operator()(PrologueID pid) const {
  91. return hash_int64_pair(pid.funcId(), pid.nArgs());
  92. }
  93. };
  94. private:
  95. FuncId m_funcId;
  96. int m_nArgs;
  97. };
  98. /**
  99. * A simple wrapper for a map from profiling prologues to TransIDs.
  100. */
  101. class PrologueToTransMap {
  102. public:
  103. void add(FuncId funcId, int numArgs, TransID transId);
  104. TransID get(FuncId funcId, int numArgs) const;
  105. private:
  106. hphp_hash_map<PrologueID, TransID, PrologueID::Hasher> m_prologueIdToTransId;
  107. };
  108. /**
  109. * A profiling record kept for each translation in JitPGO mode.
  110. */
  111. class ProfTransRec {
  112. public:
  113. ProfTransRec(TransID id, TransKind kind, Offset lastBcOff, SrcKey sk,
  114. RegionDescPtr region);
  115. ProfTransRec(TransID id, TransKind kind, SrcKey sk);
  116. ProfTransRec(TransID id, TransKind kind, SrcKey sk, int nArgs);
  117. TransID transId() const;
  118. TransKind kind() const;
  119. SrcKey srcKey() const;
  120. SrcKey lastSrcKey() const;
  121. Offset startBcOff() const;
  122. Offset lastBcOff() const;
  123. Func* func() const;
  124. FuncId funcId() const;
  125. RegionDescPtr region() const;
  126. PrologueCallersRec* prologueCallers() const;
  127. int prologueArgs() const;
  128. private:
  129. TransID m_id; // sequential ID of the associated translation
  130. TransKind m_kind;
  131. union {
  132. Offset m_lastBcOff; // offset of the last bytecode instr
  133. // for non-prologue translations
  134. int m_prologueArgs; // for prologues
  135. };
  136. RegionDescPtr m_region; // for TransProfile translations
  137. PrologueCallersRecPtr m_prologueCallers; // for TransProflogue translations
  138. SrcKey m_sk;
  139. };
  140. typedef std::unique_ptr<ProfTransRec> ProfTransRecPtr;
  141. typedef std::unordered_map<FuncId, TransIDVec> FuncProfTransMap;
  142. using FuncIdSet = hphp_hash_set<FuncId>;
  143. /**
  144. * ProfData encapsulates the profiling data kept by the JIT.
  145. */
  146. class ProfData {
  147. public:
  148. ProfData();
  149. ProfData(const ProfData&) = delete;
  150. ProfData& operator=(const ProfData&) = delete;
  151. uint32_t numTrans() const;
  152. TransID curTransID() const;
  153. bool hasTransRec(TransID id) const;
  154. SrcKey transSrcKey(TransID id) const;
  155. SrcKey transLastSrcKey(TransID id) const;
  156. Offset transStartBcOff(TransID id) const;
  157. Offset transLastBcOff(TransID id) const;
  158. PC transLastInstr(TransID id) const;
  159. Offset transStopBcOff(TransID id) const;
  160. FuncId transFuncId(TransID id) const;
  161. Func* transFunc(TransID id) const;
  162. const TransIDVec& funcProfTransIDs(FuncId funcId) const;
  163. RegionDescPtr transRegion(TransID id) const;
  164. TransKind transKind(TransID id) const;
  165. bool isKindProfile(TransID id) const;
  166. // The actual counter value, which starts at JitPGOThreshold and goes down.
  167. int64_t transCounterRaw(TransID id) const;
  168. // The absolute number of times that a translation executed.
  169. int64_t transCounter(TransID id) const;
  170. int64_t* transCounterAddr(TransID id);
  171. TransID prologueTransId(const Func* func,
  172. int nArgs) const;
  173. TransID dvFuncletTransId(const Func* func,
  174. int nArgs) const;
  175. PrologueCallersRec* prologueCallers(TransID id) const;
  176. PrologueCallersRec* prologueCallers(const Func* func, int nArgs) const;
  177. int prologueArgs(TransID id) const;
  178. TransID addTransProfile(const RegionDescPtr& region,
  179. const PostConditions& pconds);
  180. TransID addTransNonProf(TransKind kind, SrcKey sk);
  181. TransID addTransPrologue(TransKind kind, SrcKey sk,
  182. int nArgs);
  183. PrologueCallersRec* findPrologueCallersRec(const Func* func,
  184. int nArgs) const;
  185. void addPrologueMainCaller(const Func* func, int nArgs,
  186. TCA caller);
  187. void addPrologueGuardCaller(const Func* func, int nArgs,
  188. TCA caller);
  189. bool optimized(SrcKey sk) const;
  190. bool optimized(FuncId funcId) const;
  191. void setOptimized(SrcKey sk);
  192. void setOptimized(FuncId funcId);
  193. void clearOptimized(SrcKey sk);
  194. bool profiling(FuncId funcId) const;
  195. void setProfiling(FuncId funcId);
  196. void free();
  197. bool freed() const;
  198. /*
  199. * Called when we've finished promoting all the profiling translations for
  200. * `funcId' to optimized translations. This means we can throw away any
  201. * allocations we made that we won't need any more for this Func.
  202. */
  203. void freeFuncData(FuncId funcId);
  204. /*
  205. * Returns whether any block in the given func ends at the supplied offset.
  206. * This is provided in this format because the region selector wants to
  207. * terminate profiling translations at block ends (so it doesn't care where
  208. * blocks start, just where they end).
  209. */
  210. bool anyBlockEndsAt(const Func*, Offset offset);
  211. private:
  212. uint32_t m_numTrans;
  213. std::vector<ProfTransRecPtr>
  214. m_transRecs;
  215. bool m_freed;
  216. FuncProfTransMap m_funcProfTrans;
  217. ProfCounters<int64_t> m_counters;
  218. SrcKeySet m_optimizedSKs; // set of SrcKeys already optimized
  219. FuncIdSet m_optimizedFuncs; // set of funcs already optimized
  220. FuncIdSet m_profilingFuncs; // set of funcs being profiled
  221. PrologueToTransMap m_prologueDB; // maps (Func,nArgs) => prolog TransID
  222. PrologueToTransMap m_dvFuncletDB; // maps (Func,nArgs) => DV funclet
  223. // TransID
  224. hphp_hash_map<FuncId,hphp_hash_set<Offset>>
  225. m_blockEndOffsets; // func -> block end offsets
  226. };
  227. //////////////////////////////////////////////////////////////////////
  228. }}
  229. #endif