Store num args instead of offset in prologue and func entry SrcKeys
[hiphop-php.git] / hphp / runtime / vm / jit / tc-info.cpp
bloba38888512d91d5963fc5d1488a85363aa9319d0d
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present 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 +----------------------------------------------------------------------+
17 #include "hphp/runtime/vm/jit/tc.h"
18 #include "hphp/runtime/vm/jit/tc-internal.h"
20 #include "hphp/runtime/base/rds.h"
21 #include "hphp/runtime/base/runtime-option.h"
23 #include "hphp/runtime/vm/jit/code-cache.h"
24 #include "hphp/runtime/vm/jit/mcgen.h"
25 #include "hphp/runtime/vm/jit/prof-data.h"
26 #include "hphp/runtime/vm/jit/trans-db.h"
28 #include "hphp/util/data-block.h"
29 #include "hphp/util/build-info.h"
31 #include <folly/Format.h>
33 #include <algorithm>
34 #include <string>
35 #include <vector>
37 namespace HPHP::jit::tc {
39 namespace {
41 bool dumpTCCode(folly::StringPiece filename) {
42 #define OPEN_FILE(F, SUFFIX) \
43 auto const F ## name = folly::to<std::string>(filename, SUFFIX); \
44 FILE* F = fopen(F ## name .c_str(),"wb"); \
45 if (F == nullptr) return false; \
46 SCOPE_EXIT{ fclose(F); };
48 OPEN_FILE(aFile, "_a");
49 OPEN_FILE(acoldFile, "_acold");
50 OPEN_FILE(afrozenFile, "_afrozen");
52 #undef OPEN_FILE
54 // dump starting from the main region
55 auto result = true;
56 auto writeBlock = [&](const CodeBlock& cb, FILE* file) {
57 if (result) {
58 auto const count = cb.used();
59 result = fwrite(cb.base(), 1, count, file) == count;
63 writeBlock(code().main(), aFile);
64 writeBlock(code().cold(), acoldFile);
65 writeBlock(code().frozen(), afrozenFile);
66 return result;
69 bool dumpTCData() {
70 auto const dataPath = RuntimeOption::EvalDumpTCPath + "/tc_data.txt.gz";
71 gzFile tcDataFile = gzopen(dataPath.c_str(), "w");
72 if (!tcDataFile) return false;
73 SCOPE_EXIT { gzclose(tcDataFile); };
75 if (!gzprintf(tcDataFile,
76 "repo_schema = %s\n"
77 "a.base = %p\n"
78 "a.frontier = %p\n"
79 "acold.base = %p\n"
80 "acold.frontier = %p\n"
81 "afrozen.base = %p\n"
82 "afrozen.frontier = %p\n\n",
83 repoSchemaId().begin(),
84 code().main().base(), code().main().frontier(),
85 code().cold().base(), code().cold().frontier(),
86 code().frozen().base(), code().frozen().frontier())) {
87 return false;
90 if (!gzprintf(tcDataFile, "total_translations = %zu\n\n",
91 transdb::getNumTranslations())) {
92 return false;
95 // Print all translations, including their execution counters. If global
96 // counters are disabled (default), fall back to using ProfData, covering
97 // only profiling translations.
98 if (transdb::enabled()) {
99 // Admin requests do not automatically init ProfData, so do it explicitly.
100 // No need for matching exit call; data is immortal with trans DB enabled.
101 requestInitProfData();
103 const TransRec invalid;
104 assertx(!invalid.isValid());
105 for (TransID t = 0; t < transdb::getNumTranslations(); t++) {
106 auto transRec = transdb::getTransRec(t);
107 if (!transRec) transRec = &invalid;
108 auto const ret = gzputs(tcDataFile, transRec->print().c_str());
109 if (ret == -1) {
110 return false;
114 return true;
117 ////////////////////////////////////////////////////////////////////////////////
120 bool dumpEnabled() {
121 return RuntimeOption::EvalDumpTC ||
122 RuntimeOption::EvalDumpIR ||
123 RuntimeOption::EvalDumpRegion ||
124 RuntimeOption::EvalDumpInlDecision ||
125 RuntimeOption::EvalDumpCallTargets ||
126 RuntimeOption::EvalDumpLayoutCFG ||
127 RuntimeOption::EvalDumpVBC;
130 bool dump(bool ignoreLease /* = false */) {
131 if (!mcgen::initialized()) return false;
133 std::unique_lock<SimpleMutex> codeLock;
134 std::unique_lock<SimpleMutex> metaLock;
135 if (!ignoreLease) {
136 codeLock = lockCode();
137 metaLock = lockMetadata();
139 return dumpTCData() &&
140 dumpTCCode(RuntimeOption::EvalDumpTCPath + "/tc_dump");
143 std::vector<UsageInfo> getUsageInfo() {
144 std::vector<UsageInfo> tcUsageInfo;
146 code().forEachBlock([&] (const char* name, const CodeBlock& a) {
147 tcUsageInfo.emplace_back(UsageInfo{
148 std::string("code.") + name,
149 a.used(),
150 a.capacity(),
151 true
154 tcUsageInfo.emplace_back(UsageInfo{
155 "data",
156 code().data().used(),
157 code().data().capacity(),
158 true
160 tcUsageInfo.emplace_back(UsageInfo{
161 "RDS",
162 rds::usedBytes(),
163 RuntimeOption::EvalRDSSize * 3 / 4,
164 false
166 tcUsageInfo.emplace_back(UsageInfo{
167 "RDSLocal",
168 rds::usedLocalBytes(),
169 RuntimeOption::EvalRDSSize * 3 / 4,
170 false
172 tcUsageInfo.emplace_back(UsageInfo{
173 "persistentRDS",
174 rds::usedPersistentBytes(),
175 RuntimeOption::EvalRDSSize / 4,
176 false
178 return tcUsageInfo;
181 std::string getTCSpace() {
182 std::string usage;
183 size_t total_size = 0;
184 size_t total_capacity = 0;
186 auto const add_row = [&] (const UsageInfo& ui) {
187 auto const percent = ui.capacity ? 100 * ui.used / ui.capacity : 0;
189 usage += folly::format(
190 "mcg: {:9} bytes ({}%) in {}\n",
191 ui.used, percent, ui.name
192 ).str();
194 if (ui.global) {
195 total_size += ui.used;
196 total_capacity += ui.capacity;
200 auto const uis = getUsageInfo();
201 std::for_each(uis.begin(), uis.end(), add_row);
202 add_row(UsageInfo { "total", total_size, total_capacity, false });
204 return usage;
207 std::string getTCAddrs() {
208 std::string addrs;
210 code().forEachBlock([&] (const char* name, const CodeBlock& a) {
211 addrs += folly::format("{}: {}\n", name, a.base()).str();
213 return addrs;
216 std::vector<TCMemInfo> getTCMemoryUsage() {
217 std::vector<TCMemInfo> ret;
218 code().forEachBlock(
219 [&](const char* name, const CodeBlock& a) {
220 ret.emplace_back(TCMemInfo{
221 name,
222 a.used(),
223 a.numAllocs(),
224 a.numFrees(),
225 a.bytesFree(),
226 a.blocksFree()
230 return ret;