Offload rarely-used members of Class to Class::ExtraData
[hiphop-php.git] / hphp / runtime / vm / class-inl.h
blobbc6f4b813ca740451be59afda8318c9277732069
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
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_CLASS_INL_H_
18 #error "class-inl.h should only be included by class.h"
19 #endif
21 namespace HPHP {
22 ///////////////////////////////////////////////////////////////////////////////
24 inline bool Class::isZombie() const {
25 return !m_cachedClass.bound();
28 ///////////////////////////////////////////////////////////////////////////////
29 // Class::PropInitVec.
31 inline Class::PropInitVec::iterator Class::PropInitVec::begin() {
32 return m_data;
35 inline Class::PropInitVec::iterator Class::PropInitVec::end() {
36 return m_data + m_size;
39 inline size_t Class::PropInitVec::size() const {
40 return m_size;
43 inline TypedValueAux& Class::PropInitVec::operator[](size_t i) {
44 assert(i < m_size);
45 return m_data[i];
48 inline const TypedValueAux& Class::PropInitVec::operator[](size_t i) const {
49 assert(i < m_size);
50 return m_data[i];
53 ///////////////////////////////////////////////////////////////////////////////
54 // Pre- and post-allocations.
56 inline const LowClassPtr* Class::classVec() const {
57 return m_classVec;
60 inline unsigned Class::classVecLen() const {
61 return m_classVecLen;
64 ///////////////////////////////////////////////////////////////////////////////
65 // Ancestry.
67 inline uint64_t Class::classof(const Class* cls) const {
68 // If `cls' is an interface, we can simply check to see if cls is in
69 // this->m_interfaces. Otherwise, if `this' is not an interface, the
70 // classVec check will determine whether it's an instance of cls (including
71 // the case where this and cls are the same trait). Otherwise, `this' is an
72 // interface, and `cls' is not, so we need to return false. But the classVec
73 // check can never return true in that case (cls's classVec contains only
74 // non-interfaces, while this->classVec is either empty, or contains
75 // interfaces).
76 if (UNLIKELY(cls->attrs() & AttrInterface)) {
77 return this == cls ||
78 m_interfaces.lookupDefault(cls->m_preClass->name(), nullptr) == cls;
80 if (m_classVecLen >= cls->m_classVecLen) {
81 return (m_classVec[cls->m_classVecLen-1] == cls);
83 return false;
86 inline bool Class::ifaceofDirect(const StringData* name) const {
87 return m_interfaces.contains(name);
90 ///////////////////////////////////////////////////////////////////////////////
91 // Basic info.
93 inline const StringData* Class::name() const {
94 return m_preClass->name();
97 inline const PreClass* Class::preClass() const {
98 return m_preClass.get();
101 inline Class* Class::parent() const {
102 return m_parent.get();
105 inline StrNR Class::nameStr() const {
106 return m_preClass->nameStr();
109 inline StrNR Class::parentStr() const {
110 return m_preClass->parentStr();
113 inline Attr Class::attrs() const {
114 assert(Attr(m_attrCopy) == m_preClass->attrs());
115 return Attr(m_attrCopy);
118 inline int Class::getODAttrs() const {
119 return m_ODAttrs;
122 inline bool Class::isPersistent() const {
123 return attrs() & AttrPersistent;
126 ///////////////////////////////////////////////////////////////////////////////
127 // Magic methods.
129 inline const Func* Class::getCtor() const {
130 return m_ctor;
133 inline const Func* Class::getDtor() const {
134 return m_dtor;
137 inline const Func* Class::getToString() const {
138 return m_toString;
141 ///////////////////////////////////////////////////////////////////////////////
142 // Builtin classes.
144 inline bool Class::isBuiltin() const {
145 return attrs() & AttrBuiltin;
148 inline const ClassInfo* Class::clsInfo() const {
149 return m_extra->m_clsInfo;
152 inline BuiltinCtorFunction Class::instanceCtor() const {
153 return m_extra->m_instanceCtor;
156 inline BuiltinDtorFunction Class::instanceDtor() const {
157 return m_extra->m_instanceDtor;
160 inline int32_t Class::builtinODTailSize() const {
161 return m_extra->m_builtinODTailSize;
164 ///////////////////////////////////////////////////////////////////////////////
165 // Methods.
167 inline size_t Class::numMethods() const {
168 return m_methods.size();
171 inline Func* Class::getMethod(Slot idx) const {
172 auto funcVec = (LowFuncPtr*)this;
173 return funcVec[-((int32_t)idx + 1)];
176 inline void Class::setMethod(Slot idx, Func* func) {
177 auto funcVec = (LowFuncPtr*)this;
178 funcVec[-((int32_t)idx + 1)] = func;
181 inline Func* Class::lookupMethod(const StringData* methName) const {
182 Slot* idx = m_methods.find(methName);
183 if (!idx) return nullptr;
184 return getMethod(*idx);
187 ///////////////////////////////////////////////////////////////////////////////
188 // Property metadata.
190 inline size_t Class::numDeclProperties() const {
191 return m_declProperties.size();
194 inline size_t Class::numStaticProperties() const {
195 return m_staticProperties.size();
198 inline uint32_t Class::declPropNumAccessible() const {
199 return m_declPropNumAccessible;
202 inline const Class::Prop* Class::declProperties() const {
203 return m_declProperties.accessList();
206 inline const Class::SProp* Class::staticProperties() const {
207 return m_staticProperties.accessList();
210 inline Slot Class::lookupDeclProp(const StringData* propName) const {
211 return m_declProperties.findIndex(propName);
214 inline Slot Class::lookupSProp(const StringData* sPropName) const {
215 return m_staticProperties.findIndex(sPropName);
218 inline RepoAuthType Class::declPropRepoAuthType(Slot index) const {
219 return m_declProperties[index].m_repoAuthType;
222 inline RepoAuthType Class::staticPropRepoAuthType(Slot index) const {
223 return m_staticProperties[index].m_repoAuthType;
226 inline bool Class::hasDeepInitProps() const {
227 return m_hasDeepInitProps;
230 ///////////////////////////////////////////////////////////////////////////////
231 // Property initialization.
233 inline bool Class::needInitialization() const {
234 return m_needInitialization;
237 inline const Class::PropInitVec& Class::declPropInit() const {
238 return m_declPropInit;
241 inline const std::vector<const Func*>& Class::pinitVec() const {
242 return m_pinitVec;
245 ///////////////////////////////////////////////////////////////////////////////
246 // Property storage.
248 inline void Class::initPropHandle() const {
249 m_propDataCache.bind();
252 inline RDS::Handle Class::propHandle() const {
253 return m_propDataCache.handle();
256 inline RDS::Handle Class::sPropInitHandle() const {
257 return m_sPropCacheInit.handle();
260 inline RDS::Handle Class::sPropHandle(Slot index) const {
261 assert(m_sPropCacheInit.bound());
262 assert(numStaticProperties() > index);
263 return m_sPropCache[index].handle();
266 ///////////////////////////////////////////////////////////////////////////////
267 // Constants.
269 inline size_t Class::numConstants() const {
270 return m_constants.size();
273 inline const Class::Const* Class::constants() const {
274 return m_constants.accessList();
277 inline bool Class::hasConstant(const StringData* clsCnsName) const {
278 return m_constants.contains(clsCnsName);
281 ///////////////////////////////////////////////////////////////////////////////
282 // Interfaces and traits.
284 inline boost::iterator_range<const ClassPtr*> Class::declInterfaces() const {
285 return boost::make_iterator_range(
286 m_declInterfaces.get(),
287 m_declInterfaces.get() + m_numDeclInterfaces
291 inline const Class::InterfaceMap& Class::allInterfaces() const {
292 return m_interfaces;
295 inline Slot Class::traitsBeginIdx() const {
296 return m_extra->m_traitsBeginIdx;
299 inline Slot Class::traitsEndIdx() const {
300 return m_extra->m_traitsEndIdx;
303 inline const std::vector<ClassPtr>& Class::usedTraitClasses() const {
304 return m_extra->m_usedTraits;
307 inline const Class::TraitAliasVec& Class::traitAliases() const {
308 return m_extra->m_traitAliases;
311 inline const Class::RequirementMap& Class::allRequirements() const {
312 return m_requirements;
315 ///////////////////////////////////////////////////////////////////////////////
316 // Objects.
318 inline bool Class::callsCustomInstanceInit() const {
319 return m_callsCustomInstanceInit;
322 ///////////////////////////////////////////////////////////////////////////////
323 // Other methods.
325 inline RDS::Handle Class::classHandle() const {
326 return m_cachedClass.handle();
329 inline void Class::setClassHandle(RDS::Link<Class*> link) const {
330 assert(!m_cachedClass.bound());
331 m_cachedClass = link;
334 inline Class* Class::getCached() const {
335 return *m_cachedClass;
338 inline void Class::setCached() {
339 *m_cachedClass = this;
342 inline const Native::NativeDataInfo* Class::getNativeDataInfo() const {
343 return m_extra->m_nativeDataInfo;
346 inline DataType Class::enumBaseTy() const {
347 return m_enumBaseTy;
350 ///////////////////////////////////////////////////////////////////////////////
351 // ExtraData.
353 inline void Class::allocExtraData() {
354 if (!m_extra) {
355 m_extra = new ExtraData();
359 ///////////////////////////////////////////////////////////////////////////////
361 inline Attr classKindAsAttr(ClassKind kind) {
362 return static_cast<Attr>(kind);
365 inline bool isTrait(const Class* cls) {
366 return cls->attrs() & AttrTrait;
369 inline bool isEnum(const Class* cls) {
370 return cls->attrs() & AttrEnum;
373 inline bool isInterface(const Class* cls) {
374 return cls->attrs() & AttrInterface;
377 inline bool isNormalClass(const Class* cls ) {
378 return !(cls->attrs() & (AttrTrait | AttrInterface | AttrEnum));
381 inline bool isAbstract(const Class* cls) {
382 return cls->attrs() & AttrAbstract;
385 inline bool classHasPersistentRDS(const Class* cls) {
386 return cls && RDS::isPersistentHandle(cls->classHandle());
389 ///////////////////////////////////////////////////////////////////////////////