Move unique stubs to unique-stubs-resumable.cpp
[hiphop-php.git] / hphp / runtime / vm / jit / tc.h
blobf09ec63e052ff9a2d8cf3c4c4e8e6a1ef9e28d21
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 #ifndef incl_HPHP_JIT_TC_H_
18 #define incl_HPHP_JIT_TC_H_
20 #include "hphp/runtime/vm/func.h"
21 #include "hphp/runtime/vm/resumable.h"
22 #include "hphp/runtime/vm/jit/cg-meta.h"
23 #include "hphp/runtime/vm/jit/code-cache.h"
24 #include "hphp/runtime/vm/jit/ir-opcode.h"
25 #include "hphp/runtime/vm/jit/srcdb.h"
26 #include "hphp/runtime/vm/jit/stack-offsets.h"
27 #include "hphp/runtime/vm/jit/types.h"
28 #include "hphp/runtime/vm/jit/unique-stubs.h"
29 #include "hphp/util/growable-vector.h"
31 #include <folly/Optional.h>
33 #include <memory>
34 #include <string>
35 #include <vector>
37 namespace HPHP { namespace jit {
39 struct AsmInfo;
40 struct FPInvOffset;
41 struct IncomingBranch;
42 struct IRUnit;
43 struct ProfTransRec;
44 struct TransEnv;
45 struct TransLoc;
46 struct Vunit;
48 using OptView = folly::Optional<CodeCache::View>;
50 ////////////////////////////////////////////////////////////////////////////////
52 namespace tc {
54 struct TransRange {
55 TcaRange main;
56 TcaRange cold;
57 TcaRange frozen;
58 TcaRange data;
60 TransLoc loc() const;
63 struct TransMetaInfo {
64 SrcKey sk;
65 CodeCache::View emitView; // View code was emitted into (may be thread local)
66 TransKind viewKind; // TransKind used to select code view
67 TransKind transKind; // TransKind used for translation
68 TransRange range;
69 CGMeta meta;
70 TransRec transRec;
73 struct LocalTCBuffer {
74 LocalTCBuffer() = default;
75 explicit LocalTCBuffer(Address start, size_t initialSize);
76 LocalTCBuffer(LocalTCBuffer&&) = default;
77 LocalTCBuffer& operator=(LocalTCBuffer&&) = default;
79 OptView view();
80 bool valid() const { return m_main.base() != nullptr; }
82 private:
83 CodeBlock m_main;
84 CodeBlock m_cold;
85 CodeBlock m_frozen;
86 DataBlock m_data;
89 struct FuncMetaInfo {
90 FuncMetaInfo() = default;
91 FuncMetaInfo(Func* f, LocalTCBuffer&& buf)
92 : fid(f->getFuncId())
93 , func(f)
94 , tcBuf(std::move(buf))
97 FuncMetaInfo(FuncMetaInfo&&) = default;
98 FuncMetaInfo& operator=(FuncMetaInfo&&) = default;
100 FuncId fid;
101 Func* func;
102 LocalTCBuffer tcBuf;
103 std::vector<ProfTransRec*> prologues;
104 std::vector<TransMetaInfo> translations;
107 ////////////////////////////////////////////////////////////////////////////////
110 * Returns true iff we already have Eval.JitMaxTranslations translations
111 * recorded in srcRec.
113 bool reachedTranslationLimit(TransKind kind, SrcKey sk, const SrcRec& srcRec);
116 * Emit machine code for env. Returns folly::none if the global translation
117 * limit has been reached, generates an interp request if vunit is null or
118 * codegen fails. If optDst is set it must be a thread local view and the
119 * code lock will not be acquired while writing to it.
121 * The resulting translation will not yet be live.
123 folly::Optional<TransMetaInfo> emitTranslation(
124 TransEnv env,
125 OptView optDst = folly::none
129 * Make a translation generated by emitTranslation live. If the translation was
130 * emitted into a per-thread buffer then optSrcView must be the view into which
131 * it was emitted, it will be relocated at the end of the live TC.
133 folly::Optional<TransLoc> publishTranslation(
134 TransMetaInfo info,
135 OptView optSrcView = folly::none
139 * Publish a set of optimized translations associated with a particular
140 * function. It is assumed that these translations have been emitted into per-
141 * thread buffers and will need to be relocated.
143 void publishOptFunction(FuncMetaInfo info);
146 * Acquires the code and metadata locks once and relocates all functions in
147 * sorted list.
149 void publishSortedOptFunctions(std::vector<FuncMetaInfo> infos);
152 * Emit a new prologue for func-- returns nullptr if the global translation
153 * limit has been reached.
155 TCA emitFuncPrologue(Func* func, int argc, TransKind kind);
158 * Emits an optimized prologue for rec.
160 * Smashes the callers of the prologue for rec and updates the cached func
161 * prologue.
163 TCA emitFuncPrologueOpt(ProfTransRec* rec);
166 * Emit the prologue dispatch for func which contains dvs DV initializers, and
167 * return its start address. The `kind' of translation argument is used to
168 * decide what area of the code cache will be used (hot, main, or prof).
170 TCA emitFuncBodyDispatch(Func* func, const DVFuncletsVec& dvs, TransKind kind);
172 ////////////////////////////////////////////////////////////////////////////////
175 * True iff the global translation limit has not yet been reached.
177 bool canTranslate();
180 * Whether we should emit a translation of kind for func, ignoring the cap on
181 * overall TC size.
183 bool shouldTranslateNoSizeLimit(const Func* func, TransKind kind);
186 * Whether we should emit a translation of kind for func.
188 bool shouldTranslate(const Func* func, TransKind kind);
191 * Whether we are still profiling new functions.
193 bool shouldProfileNewFuncs();
196 * Whether we should try profile-guided optimization when translating `func'.
198 bool profileFunc(const Func* func);
201 * Attempt to discard profData via the treadmill if it is no longer needed.
203 void checkFreeProfData();
205 ////////////////////////////////////////////////////////////////////////////////
208 * SrcRec for sk or nullptr if no SrcRec has been created.
210 SrcRec* findSrcRec(SrcKey sk);
213 * Create a SrcRec for sk with an sp offset of spOff.
215 void createSrcRec(SrcKey sk, FPInvOffset spOff);
217 ////////////////////////////////////////////////////////////////////////////////
220 * Assert ownership of the CodeCache by this thread.
222 * Must be held even if the current thread owns the global write lease.
224 void assertOwnsCodeLock(OptView v = folly::none);
227 * Assert ownership of the tc metadata by this thread.
229 * Must be held even if the current thread owns the global write lease.
231 void assertOwnsMetadataLock();
233 ////////////////////////////////////////////////////////////////////////////////
236 * Get the table of unique stubs
238 * Pre: processInit()
240 ALWAYS_INLINE const UniqueStubs& ustubs() {
241 extern UniqueStubs g_ustubs;
242 return g_ustubs;
246 * Perform one time process initialization for the structures associated with
247 * this module.
249 void processInit();
252 * Perform process shutdown functions for the TC including joining any
253 * outstanding background threads.
255 void processExit();
257 ////////////////////////////////////////////////////////////////////////////////
260 * Perform TC related request initialization and teardown.
262 void requestInit();
263 void requestExit();
266 * Returns the total size of the TC now and at the beginning of this request,
267 * in bytes. Note that the code may have been emitted by other threads.
269 * Pre: requestInit()
271 void codeEmittedThisRequest(size_t& requestEntry, size_t& now);
273 ////////////////////////////////////////////////////////////////////////////////
276 * Reclaim all TC space associated with func
278 * Before any space is reclaimed the following actions will be performed:
279 * (1) Smash all prologues
280 * (2) Smash all callers to bind-call unique stubs
281 * (3) Erase all call meta-data for calls into function
283 * After all calls and prologues have been smashed any on-going requests will be
284 * allowed to complete before TC Space will be reclaimed for:
285 * (1) All prologues
286 * (2) All translations
287 * (3) All anchor translations
289 * This function should only be called from Func::destroy() and may access the
290 * fullname and ID of the function.
292 void reclaimFunction(const Func* func);
295 * Allows TC space for translations in trans to be reused in future
296 * translations.
298 * Reclaiming a translation will:
299 * (1) Mark bytes available for reuse in the code-blocks associated with
300 * the translation
301 * (2) Erase any IBs from translation into other SrcRecs
302 * (3) Erase any jump annotations in MCGenerator used to generate optimized
303 * traces
304 * (4) Erase an metadata about smashed calls in the translation from both the
305 * reuse-tc module and the prof-data module
307 * The translation _must_ be unreachable before reclaimTranslation() is called,
308 * this is generally done by calling reclaimFunction() or performing
309 * replaceOldTranslations() on a SrcRec
311 void reclaimTranslations(GrowableVector<TransLoc>&& trans);
314 * Free an ephemeral stub.
316 void freeTCStub(TCA stub);
318 ////////////////////////////////////////////////////////////////////////////////
321 * Emit checks for (and hooks into) an attached debugger in front of each
322 * translation in `unit' or for `SrcKey{func, offset, resumed}'.
324 bool addDbgGuards(const Unit* unit);
325 bool addDbgGuard(const Func* func, Offset offset, ResumeMode resumeMode);
327 ////////////////////////////////////////////////////////////////////////////////
329 struct UsageInfo {
330 std::string name;
331 size_t used;
332 size_t capacity;
333 bool global;
337 * Get UsageInfo data for all the TC code sections, including global data, and
338 * also for RDS.
340 std::vector<UsageInfo> getUsageInfo();
343 * Like getUsageInfo(), but formatted as a pleasant string.
345 std::string getTCSpace();
348 * Return a string containing the names and start addresses of all TC code
349 * sections.
351 std::string getTCAddrs();
354 * Dump the translation cache to files in RuntimeOption::EvalDumpTCPath
355 * (default: /tmp), returning success.
357 bool dump(bool ignoreLease = false);
359 struct TCMemInfo {
360 std::string name;
361 size_t used;
362 size_t allocs;
363 size_t frees;
364 size_t free_size;
365 size_t free_blocks;
369 * Get per section memory usage data for the TC.
371 std::vector<TCMemInfo> getTCMemoryUsage();
373 ////////////////////////////////////////////////////////////////////////////////
376 * Convert between TC addresses and offsets.
378 extern CodeCache* g_code;
379 ALWAYS_INLINE TCA offsetToAddr(uint32_t off) {
380 return g_code->toAddr(off);
382 ALWAYS_INLINE uint32_t addrToOffset(CTCA addr) {
383 return g_code->toOffset(addr);
387 * Check if `addr' is an address within the TC.
389 bool isValidCodeAddress(TCA addr);
392 * Check if `addr' is an address within the profile code block in the TC.
394 bool isProfileCodeAddress(TCA addr);
396 ////////////////////////////////////////////////////////////////////////////////
399 relocate using data from perf.
400 If time is non-negative, its used as the time to run perf record.
401 If time is -1, we pick a random subset of translations, and relocate them
402 in a random order.
403 If time is -2, we relocate all of the translations.
405 Currently we don't ever relocate anything from frozen (or prof). We also
406 don't relocate the cold portion of translations; but we still need to know
407 where those are in order to relocate back-references to the code that was
408 relocated.
410 void liveRelocate(int time);
412 inline void liveRelocate(bool random) {
413 return liveRelocate(random ? -1 : 20);
417 * Relocate a new translation to the current frontiers of main and cold. Code
418 * in frozen is not moved.
420 * TODO(t10543562): This can probably be merged with relocateNewTranslation.
422 void relocateTranslation(
423 const IRUnit* unit,
424 CodeBlock& main, CodeBlock& main_in, CodeAddress main_start,
425 CodeBlock& cold, CodeBlock& cold_in, CodeAddress cold_start,
426 CodeBlock& frozen, CodeAddress frozen_start,
427 AsmInfo* ai, CGMeta& meta
431 * Record data for live relocations.
433 void recordPerfRelocMap(
434 TCA start, TCA end,
435 TCA coldStart, TCA coldEnd,
436 SrcKey sk, int argNum,
437 const GrowableVector<IncomingBranch> &incomingBranches,
438 CGMeta& fixups);
440 ////////////////////////////////////////////////////////////////////////////////
443 * Information about the number of bound calls, branches, and tracked functions
444 * for use in logging.
446 int smashedCalls();
447 int smashedBranches();
448 int recordedFuncs();
451 * Record a jmp at address toSmash to SrcRec sr.
453 * When a translation is reclaimed we remove all annotations from all SrcRecs
454 * containing IBs from the translation so that they cannot be inadvertently
455 * smashed in the process of replaceOldTranslations()
457 void recordJump(TCA toSmash, SrcRec* sr);
460 * Insert a jump to destSk at toSmash. If no top translation for destSk exists
461 * no action is performed. On return, the value of smashed indicated whether a
462 * new address was written into the TC.
464 TCA bindJmp(TCA toSmash, SrcKey destSk, TransFlags trflags, bool& smashed);
467 * Insert the address for branches to destSk at toSmash. Upon return, the value
468 * of smashed indicates whether an address was written into the TC.
470 TCA bindAddr(TCA toSmash, SrcKey destSk, TransFlags trflags, bool& smashed);
473 * Bind a call to start at toSmash, where start is the prologue for callee, when
474 * invoked with nArgs.
476 void bindCall(TCA toSmash, TCA start, Func* callee, int nArgs, bool immutable);
480 #endif