2 +----------------------------------------------------------------------+
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_
31 #include <sys/types.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"
41 ///////////////////////////////////////////////////////////////////////////////
43 class Repo
: public RepoProxy
{
44 static SimpleMutex s_lock
;
45 static unsigned s_nRepos
;
50 // Do not directly instantiate this class; a thread-local creates one per
51 // thread on demand when Repo::get() is called.
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();
66 const char* dbName(int repoId
) const {
67 assert(repoId
< RepoIdCount
);
70 sqlite3
* dbc() const { return m_dbc
; }
71 int repoIdForNewUnit(UnitOrigin unitOrigin
) const {
73 case UnitOrigin::File
:
74 return m_localWritable
? RepoIdLocal
: RepoIdCentral
;
75 case UnitOrigin::Eval
:
82 std::string
repoName(int repoId
) const {
84 case RepoIdLocal
: return m_localRepo
;
85 case RepoIdCentral
: return m_centralRepo
;
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
106 size_t stringLengthLimit() const;
109 * Return a vector of (filepath, MD5) for every unit in central
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
);
133 * Used during repo creation to associate the supplied GlobalData
134 * with the repo that was being built. Also saves the global litstr
137 * No other threads may be reading or writing the repo GlobalData
138 * when this is called.
140 void saveGlobalData(GlobalData newData
);
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
];
160 std::string
table(int repoId
, const char* tablePrefix
);
161 void exec(const std::string
& sQuery
);
167 void rollback(); // nothrow
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
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
];
195 std::string
insertSchema(const char* path
);
196 bool openCentral(const char* repoPath
, std::string
& errorMsg
);
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
);
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
;
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
;
225 PreClassRepoProxy m_pcrp
;
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 //////////////////////////////////////////////////////////////////////