Store num args instead of offset in prologue and func entry SrcKeys
[hiphop-php.git] / hphp / runtime / vm / srckey-inl.h
blob6ee9e2534de3161020faf05d4aee44975e4af5e1
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 #include "hphp/runtime/vm/func.h"
19 namespace HPHP {
21 ///////////////////////////////////////////////////////////////////////////////
23 inline SrcKey::SrcKey()
24 : m_s{FuncId::Invalid, 0, encodeResumeMode(ResumeMode::None)}
27 inline SrcKey::SrcKey(const Func* f, Offset off, ResumeMode resumeMode)
28 : m_s{f->getFuncId(), (uint32_t)off, encodeResumeMode(resumeMode)}
30 assertx((uint32_t)off >> kNumOffsetBits == 0);
33 inline SrcKey::SrcKey(const Func* f, PC pc, ResumeMode resumeMode)
34 : m_s{f->getFuncId(), (uint32_t)f->offsetOf(pc), encodeResumeMode(resumeMode)}
36 assertx((uint32_t)f->offsetOf(pc) >> kNumOffsetBits == 0);
39 inline SrcKey::SrcKey(FuncId funcId, Offset off, ResumeMode resumeMode)
40 : m_s{funcId, (uint32_t)off, encodeResumeMode(resumeMode)}
42 assertx((uint32_t)off >> kNumOffsetBits == 0);
45 inline SrcKey::SrcKey(const Func* f, uint32_t numArgs, PrologueTag)
46 : m_s{f->getFuncId(), numArgs, encodePrologue()}
48 assertx(numArgs >> kNumOffsetBits == 0);
51 inline SrcKey::SrcKey(const Func* f, uint32_t numArgs, FuncEntryTag)
52 : m_s{f->getFuncId(), numArgs, encodeFuncEntry()}
54 assertx(numArgs >> kNumOffsetBits == 0);
57 inline SrcKey::SrcKey(SrcKey other, Offset off)
58 : m_s{other.funcID(), (uint32_t)off, other.m_s.m_resumeModeAndTags}
60 assertx((uint32_t)off >> kNumOffsetBits == 0);
63 inline SrcKey::SrcKey(AtomicInt in)
64 : m_atomicInt{in}
67 inline SrcKey SrcKey::fromAtomicInt(AtomicInt in) {
68 return SrcKey {in};
71 ///////////////////////////////////////////////////////////////////////////////
73 inline bool SrcKey::valid() const {
74 auto const funcID = m_s.m_funcID;
75 assertx(
76 funcID.isInvalid() || funcID.isDummy() ||
77 (prologue() && numEntryArgs() <= func()->numNonVariadicParams() + 1) ||
78 (funcEntry() && numEntryArgs() <= func()->numNonVariadicParams()) ||
79 (!prologue() && !funcEntry() && offset() < func()->bclen())
81 return !funcID.isInvalid();
84 inline SrcKey::AtomicInt SrcKey::toAtomicInt() const {
85 return m_atomicInt;
88 inline size_t SrcKey::stableHash() const {
89 return folly::hash::hash_combine(
90 func()->stableHash(),
91 m_s.m_offsetOrNumArgs,
92 m_s.m_resumeModeAndTags
96 inline FuncId SrcKey::funcID() const {
97 assertx(!m_s.m_funcID.isInvalid());
98 return m_s.m_funcID;
101 inline Offset SrcKey::offset() const {
102 assertx(!prologue() && !funcEntry());
103 return m_s.m_offsetOrNumArgs;
106 inline Offset SrcKey::entryOffset() const {
107 assertx(prologue() || funcEntry());
108 return func()->getEntryForNumArgs(numEntryArgs());
111 inline uint32_t SrcKey::numEntryArgs() const {
112 assertx(prologue() || funcEntry());
113 return m_s.m_offsetOrNumArgs;
116 inline std::string SrcKey::printableOffset() const {
117 auto const off = !prologue() && !funcEntry() ? offset() : entryOffset();
118 return std::to_string(off);
121 inline bool SrcKey::hasThis() const {
122 if (!func()->cls()) return false;
123 return prologue() ? !func()->isStaticInPrologue() : !func()->isStatic();
126 inline ResumeMode SrcKey::resumeMode() const {
127 return m_s.m_resumeModeAndTags < 3
128 ? (ResumeMode)m_s.m_resumeModeAndTags : ResumeMode::None;
131 inline bool SrcKey::prologue() const {
132 return m_s.m_resumeModeAndTags == 3;
135 inline bool SrcKey::funcEntry() const {
136 return m_s.m_resumeModeAndTags == 4;
139 inline uint32_t SrcKey::encodeResumeMode(ResumeMode resumeMode) {
140 assertx((uint8_t)resumeMode >> kNumModeBits == 0);
141 assertx((uint8_t)resumeMode < 3);
142 return (uint8_t)resumeMode;
145 inline uint32_t SrcKey::encodePrologue() {
146 assertx(3 >> kNumModeBits == 0);
147 return 3;
150 inline uint32_t SrcKey::encodeFuncEntry() {
151 assertx(4 >> kNumModeBits == 0);
152 return 4;
155 inline const Func* SrcKey::func() const {
156 return Func::fromFuncId(m_s.m_funcID);
159 inline const Unit* SrcKey::unit() const {
160 return func()->unit();
163 inline Op SrcKey::op() const {
164 assertx(!prologue() && !funcEntry());
165 return func()->getOp(offset());
168 inline PC SrcKey::pc() const {
169 assertx(!prologue() && !funcEntry());
170 return func()->at(offset());
173 inline int SrcKey::lineNumber() const {
174 if (prologue() || funcEntry()) return func()->line1();
175 return func()->getLineNumber(offset());
178 ///////////////////////////////////////////////////////////////////////////////
180 inline void SrcKey::setOffset(Offset o) {
181 assertx((uint32_t)o >> kNumOffsetBits == 0);
182 assertx(!prologue() && !funcEntry());
183 m_s.m_offsetOrNumArgs = (uint32_t)o;
186 inline OffsetSet SrcKey::succOffsets() const {
187 assertx(!prologue());
188 if (funcEntry()) return {entryOffset()};
189 return instrSuccOffsets(pc(), func());
192 inline void SrcKey::advance(const Func* f) {
193 assertx(!prologue());
194 if (funcEntry()) {
195 m_s.m_offsetOrNumArgs = entryOffset();
196 m_s.m_resumeModeAndTags = encodeResumeMode(ResumeMode::None);
197 } else {
198 m_s.m_offsetOrNumArgs += instrLen((f ? f : func())->at(offset()));
202 inline SrcKey SrcKey::advanced(const Func* f) const {
203 auto tmp = *this;
204 tmp.advance(f);
205 return tmp;
208 inline SrcKey SrcKey::withFuncID(FuncId funcId) const {
209 auto tmp = *this;
210 tmp.m_s.m_funcID = funcId;
211 return tmp;
214 inline bool SrcKey::operator==(const SrcKey& r) const {
215 return m_atomicInt == r.m_atomicInt;
218 inline bool SrcKey::operator!=(const SrcKey& r) const {
219 return m_atomicInt != r.m_atomicInt;
222 ///////////////////////////////////////////////////////////////////////////////