Add support for HHBC ops with 5 immediates
[hiphop-php.git] / hphp / runtime / base / rds-header.h
blob96eb4e7f918967f239dc6bd576b30992f0dd40a8
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_RUNTIME_RDS_HEADER_H_
18 #define incl_HPHP_RUNTIME_RDS_HEADER_H_
20 #include <atomic>
21 #include <cstddef>
23 #include "hphp/runtime/base/rds.h"
24 #include "hphp/runtime/vm/bytecode.h"
25 #include "hphp/runtime/vm/minstr-state.h"
27 namespace HPHP {
30 * Do not access this struct directly from rds::header(). Use the accessors in
31 * runtime/vm/vm-regs.h.
33 struct VMRegs {
34 /* VM evaluation stack. Grows down in memory in multiples of 16 bytes - the
35 * size of a TypedValue. */
36 Stack stack;
38 /* VM frame pointer. Contains information about the current executing
39 * function, class context, caller, and a base pointer for accessing local
40 * variables. */
41 ActRec* fp;
43 /* VM program counter. Points to the beginning of the currently executing
44 * bytecode instruction. */
45 PC pc;
47 /* Scratch space for use by member instructions. */
48 MInstrState mInstrState;
50 /* First ActRec of this VM instance. */
51 ActRec* firstAR;
53 /* If the current VM nesting level is dispatchBB() as called by
54 * MCGenerator::handleResume(), this is set to what vmfp() was on the first
55 * entry to dispatchBB(). Otherwise, it's nullptr. See jitReturnPre() and
56 * jitReturnPost() in bytecode.cpp for usage. Note that we will have at most
57 * one active call to handleResume() in each VM nesting level, which is why
58 * this is just a single pointer. */
59 ActRec* jitCalledFrame;
61 TYPE_SCAN_CUSTOM() {
62 // ActRecs are always interior pointers so the type-scanner won't
63 // automatically enqueue them.
64 scanner.scan(fp);
65 scanner.scan(mInstrState);
66 scanner.scan(firstAR);
67 scanner.scan(jitCalledFrame);
71 namespace rds {
74 * Statically layed-out header that goes at the front of RDS.
76 struct Header {
78 * Combination of surprise flags and the limit (lowest address) of the
79 * evaluation stack. May be written to by other threads.
81 * At various points, the runtime will check whether this word contains a
82 * higher number than what it believes the evaluation stack needs to be
83 * (remember the eval stack grows down), which combines a stack overflow
84 * check and a check for unusual conditions. If this check triggers, the
85 * runtime will do more detailed checks to see if it's actually dealing with
86 * a stack overflow, or a surprise condition.
88 * All the surprise flag bits are in the upper 16 bits of this value, which
89 * must be zero if it is actually a pointer to the lowest address of the
90 * evaluation stack (the normal, "unsurprised" situation)---if one of the
91 * surprise flags is set, the pointer will be higher than any legal eval
92 * stack pointer and we'll go to a slow path to handle possible unusual
93 * conditions (e.g. OOM). (This is making use of the x64 property that
94 * "canonical form" addresses have all their upper bits the same as bit 47,
95 * and that this is zero for linux userland pointers.)
97 std::atomic<size_t> stackLimitAndSurprise;
99 #ifndef NDEBUG
101 * In builds with assertions enabled, we write-protect non-persistent RDS
102 * while in certain parts of the jit. We still want to allow jit threads to
103 * write to the surprise flags, so we don't write-protect the first page and
104 * push the rest of Header to the next page.
106 * If the Header ends up on a page that is larger than 4096 bytes, vmRegs
107 * might not be write-protected when we want it to be, but this is just a
108 * debugging aid and isn't necessary for correctness. We use 4096 bytes of
109 * padding rather than 4096 - sizeof(size_t) to not disturb the relative
110 * alignment of vmRegs.
112 const char padding[4096];
113 #endif
115 VMRegs vmRegs;
116 GenNumber currentGen;
120 * Access to the statically layed out header.
122 inline Header* header() {
123 return static_cast<Header*>(tl_base);
126 constexpr ptrdiff_t kSurpriseFlagsOff = offsetof(Header,
127 stackLimitAndSurprise);
128 constexpr ptrdiff_t kVmRegsOff = offsetof(Header, vmRegs);
129 constexpr ptrdiff_t kVmspOff = kVmRegsOff + offsetof(VMRegs, stack) +
130 Stack::topOfStackOffset();
131 constexpr ptrdiff_t kVmfpOff = kVmRegsOff + offsetof(VMRegs, fp);
132 constexpr ptrdiff_t kVmpcOff = kVmRegsOff + offsetof(VMRegs, pc);
133 constexpr ptrdiff_t kVmFirstAROff = kVmRegsOff + offsetof(VMRegs, firstAR);
134 constexpr ptrdiff_t kVmMInstrStateOff = kVmRegsOff +
135 offsetof(VMRegs, mInstrState);
137 static_assert((kVmMInstrStateOff % 16) == 0,
138 "MInstrState should be 16-byte aligned in rds::Header");
142 #endif