2 +----------------------------------------------------------------------+
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_
23 #include "hphp/runtime/base/rds.h"
24 #include "hphp/runtime/vm/bytecode.h"
25 #include "hphp/runtime/vm/minstr-state.h"
30 * Do not access this struct directly from rds::header(). Use the accessors in
31 * runtime/vm/vm-regs.h.
34 /* VM evaluation stack. Grows down in memory in multiples of 16 bytes - the
35 * size of a TypedValue. */
38 /* VM frame pointer. Contains information about the current executing
39 * function, class context, caller, and a base pointer for accessing local
43 /* VM program counter. Points to the beginning of the currently executing
44 * bytecode instruction. */
47 /* Scratch space for use by member instructions. */
48 MInstrState mInstrState
;
50 /* First ActRec of this VM instance. */
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
;
62 // ActRecs are always interior pointers so the type-scanner won't
63 // automatically enqueue them.
65 scanner
.scan(mInstrState
);
66 scanner
.scan(firstAR
);
67 scanner
.scan(jitCalledFrame
);
74 * Statically layed-out header that goes at the front of RDS.
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
;
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];
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");