Use custom AssemblyAnnotationWriter to improve vasm/llvm printing
[hiphop-php.git] / hphp / runtime / vm / repo.h
blob404a6d65029cf2bfc373323ca3aa12ca3fa9871a
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2014 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 #ifndef incl_HPHP_VM_REPO_H_
18 #define incl_HPHP_VM_REPO_H_
20 #include <vector>
21 #include <utility>
22 #include <string>
23 #include <memory>
24 #include <cstdlib>
26 #include <sqlite3.h>
28 // For sysconf(3).
29 #include <unistd.h>
30 // For getpwuid_r(3).
31 #include <sys/types.h>
32 #include <pwd.h>
34 #include "hphp/runtime/vm/class.h"
35 #include "hphp/runtime/vm/func.h"
36 #include "hphp/runtime/vm/litstr-repo-proxy.h"
37 #include "hphp/runtime/vm/preclass-emitter.h"
38 #include "hphp/runtime/vm/unit-emitter.h"
40 namespace HPHP {
41 ///////////////////////////////////////////////////////////////////////////////
43 class Repo : public RepoProxy {
44 static SimpleMutex s_lock;
45 static unsigned s_nRepos;
47 public:
48 struct GlobalData;
50 // Do not directly instantiate this class; a thread-local creates one per
51 // thread on demand when Repo::get() is called.
52 static Repo& get();
53 static bool prefork();
54 static void postfork(pid_t pid);
57 * In some command line programs that use the repo, it is necessary
58 * to shut it down at some point in the process. (See hhbbc.) This
59 * function accomplishes this.
61 static void shutdown();
63 Repo();
64 ~Repo();
66 const char* dbName(int repoId) const {
67 assert(repoId < RepoIdCount);
68 return kDbs[repoId];
70 sqlite3* dbc() const { return m_dbc; }
71 int repoIdForNewUnit(UnitOrigin unitOrigin) const {
72 switch (unitOrigin) {
73 case UnitOrigin::File:
74 return m_localWritable ? RepoIdLocal : RepoIdCentral;
75 case UnitOrigin::Eval:
76 return m_evalRepoId;
77 default:
78 assert(false);
79 return RepoIdInvalid;
82 std::string repoName(int repoId) const {
83 switch (repoId) {
84 case RepoIdLocal: return m_localRepo;
85 case RepoIdCentral: return m_centralRepo;
86 default: return "?";
90 UnitRepoProxy& urp() { return m_urp; }
91 PreClassRepoProxy& pcrp() { return m_pcrp; }
92 FuncRepoProxy& frp() { return m_frp; }
93 LitstrRepoProxy& lsrp() { return m_lsrp; }
95 static void setCliFile(const std::string& cliFile);
97 std::unique_ptr<Unit> loadUnit(const std::string& name, const MD5& md5);
98 bool findFile(const char* path, const std::string& root, MD5& md5);
99 bool insertMd5(UnitOrigin unitOrigin, UnitEmitter* ue, RepoTxn& txn);
100 void commitMd5(UnitOrigin unitOrigin, UnitEmitter* ue);
103 * Return the largest size for a static string that can be inserted into the
104 * repo.
106 size_t stringLengthLimit() const;
109 * Return a vector of (filepath, MD5) for every unit in central
110 * repo.
112 std::vector<std::pair<std::string,MD5>> enumerateUnits(
113 int repoId, bool preloadOnly, bool warn);
116 * Load the repo-global metadata table, including the global litstr
117 * table. Normally called during process initialization.
119 void loadGlobalData(bool allowFailure = false);
122 * Access to global data.
124 * Pre: loadGlobalData() already called, and
125 * RuntimeOption::RepoAuthoritative.
127 static const GlobalData& global() {
128 assert(RuntimeOption::RepoAuthoritative);
129 return s_globalData;
133 * Used during repo creation to associate the supplied GlobalData
134 * with the repo that was being built. Also saves the global litstr
135 * table.
137 * No other threads may be reading or writing the repo GlobalData
138 * when this is called.
140 void saveGlobalData(GlobalData newData);
142 private:
144 * RepoStmts for setting/getting file hashes.
146 struct InsertFileHashStmt : public RepoProxy::Stmt {
147 InsertFileHashStmt(Repo& repo, int repoId) : Stmt(repo, repoId) {}
148 void insert(RepoTxn& txn, const StringData* path, const MD5& md5);
151 struct GetFileHashStmt : public RepoProxy::Stmt {
152 GetFileHashStmt(Repo& repo, int repoId) : Stmt(repo, repoId) {}
153 bool get(const char* path, MD5& md5);
156 InsertFileHashStmt m_insertFileHash[RepoIdCount];
157 GetFileHashStmt m_getFileHash[RepoIdCount];
159 public:
160 std::string table(int repoId, const char* tablePrefix);
161 void exec(const std::string& sQuery);
163 void begin();
164 private:
165 void txPop();
166 public:
167 void rollback(); // nothrow
168 void commit();
169 bool insertUnit(UnitEmitter* ue, UnitOrigin unitOrigin,
170 RepoTxn& txn); // nothrow
171 void commitUnit(UnitEmitter* ue, UnitOrigin unitOrigin); // nothrow
173 // All database table names use the schema ID (md5 checksum based on the
174 // source code) as a suffix. For example, if the schema ID is
175 // "b02c58478ce89719782fea89f3009295", the file magic is stored in the
176 // magic_b02c58478ce89719782fea89f3009295 table:
178 // CREATE TABLE magic_b02c58478ce89719782fea89f3009295(product[TEXT]);
179 // INSERT INTO magic_b02c58478ce89719782fea89f3009295 VALUES(
180 // 'facebook.com HipHop Virtual Machine bytecode repository');
182 // This allows multiple schemas to coexist in the same database, which is
183 // especially important if multiple versions of hhvm are in use at the same
184 // time.
185 private:
186 // Magic product constant used to distinguish a .hhbc database.
187 static const char* kMagicProduct;
188 static const char* kSchemaPlaceholder;
190 static const char* kDbs[RepoIdCount];
192 void connect();
193 void disconnect();
194 void initCentral();
195 std::string insertSchema(const char* path);
196 bool openCentral(const char* repoPath, std::string& errorMsg);
197 void initLocal();
198 void attachLocal(const char* repoPath, bool isWritable);
199 void pragmas(int repoId);
200 void getIntPragma(int repoId, const char* name, int& val);
201 void setIntPragma(int repoId, const char* name, int val);
202 void getTextPragma(int repoId, const char* name, std::string& val);
203 void setTextPragma(int repoId, const char* name, const char* val);
204 bool initSchema(int repoId, bool& isWritable, std::string& errorMsg);
205 bool schemaExists(int repoId);
206 bool createSchema(int repoId, std::string& errorMsg);
207 bool writable(int repoId);
209 private:
210 static std::string s_cliFile;
211 static GlobalData s_globalData;
213 std::string m_localRepo;
214 std::string m_centralRepo;
215 sqlite3* m_dbc; // Database connection, shared by multiple attached databases.
216 bool m_localReadable;
217 bool m_localWritable;
218 int m_evalRepoId;
219 unsigned m_txDepth; // Transaction nesting depth.
220 bool m_rollback; // If true, rollback rather than commit.
221 RepoStmt m_beginStmt;
222 RepoStmt m_rollbackStmt;
223 RepoStmt m_commitStmt;
224 UnitRepoProxy m_urp;
225 PreClassRepoProxy m_pcrp;
226 FuncRepoProxy m_frp;
227 LitstrRepoProxy m_lsrp;
230 //////////////////////////////////////////////////////////////////////
233 * Try to commit a vector of unit emitters to the current repo.
235 void batchCommit(std::vector<std::unique_ptr<UnitEmitter>>);
237 //////////////////////////////////////////////////////////////////////
241 #endif