Arquivos
hhvm/hphp/runtime/base/array/array_inline.h
T
Andrei Alexandrescu a2e76eb7b2 Eliminate static noise from .h files
The codebase had several namespace-level static data definitions and function definitions. Using namespace-level "static" in a .h file is near-always a bad idea, as follows:

  - for simple types, static is implied. Example: "const int x = 42;" is the same as "static const int x = 42;"
  - for aggregate types, static linkage implies that a copy of the aggregate will appear in every compilation unit that includes the header.
  - for functions, static means the function will have a separate body generated in each compilation unit including the header.
  - in several places functions were defined 'static inline', which is just as bad. 'inline' is just a hint which means the function may end up having a body (and actually more due to 'static').

True, gnu's linker has means to remove duplicate definition, but that's not always guaranteed or possible (think e.g. static functions that define static data inside, ouch). So static is useless at best and pernicious at worst. We should never, ever use static at namespace level in headers. I will create a bootcamp task for a lint rule.

I expected the performance to be neutral after the change, but in fact there's a significant drop in instruction count and therefore a measurable reduction in CPU time: https://our.intern.facebook.com/intern/perflab/details.php?eq_id=431903
2013-06-06 11:39:13 -07:00

171 linhas
5.5 KiB
C++

/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_ARRAY_INLINE_H_
#define incl_HPHP_ARRAY_INLINE_H_
#include "hphp/runtime/base/array/array_data.h"
#include "hphp/runtime/base/complex_types.h"
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
namespace {
typedef Variant::TypedValueAccessor TypedValueAccessor;
inline bool isIntKey(TypedValueAccessor tva) {
return Variant::GetAccessorType(tva) <= KindOfInt64;
}
inline int64_t getIntKey(TypedValueAccessor tva) {
return Variant::GetInt64(tva);
}
inline StringData *getStringKey(TypedValueAccessor tva) {
return Variant::GetStringData(tva);
}
}
inline bool ArrayData::exists(CStrRef k) const {
assert(IsValidKey(k));
return exists(k.get());
}
inline bool ArrayData::exists(CVarRef k) const {
assert(IsValidKey(k));
TypedValueAccessor tvk = k.getTypedAccessor();
return isIntKey(tvk) ? exists(getIntKey(tvk)) :
exists(getStringKey(tvk));
}
inline CVarRef ArrayData::get(CStrRef k, bool error) const {
assert(IsValidKey(k));
return get(k.get(), error);
}
inline CVarRef ArrayData::get(CVarRef k, bool error) const {
assert(IsValidKey(k));
TypedValueAccessor tvk = k.getTypedAccessor();
return isIntKey(tvk) ? get(getIntKey(tvk), error) :
get(getStringKey(tvk), error);
}
inline ssize_t ArrayData::getIndex(CStrRef k) const {
assert(IsValidKey(k));
return getIndex(k.get());
}
inline ssize_t ArrayData::getIndex(CVarRef k) const {
assert(IsValidKey(k));
TypedValueAccessor tvk = k.getTypedAccessor();
return isIntKey(tvk) ? getIndex(getIntKey(tvk)) :
getIndex(getStringKey(tvk));
}
inline ArrayData* ArrayData::lval(CStrRef k, Variant *&ret, bool copy,
bool checkExist) {
assert(IsValidKey(k));
return lval(k.get(), ret, copy, checkExist);
}
inline ArrayData* ArrayData::lval(CVarRef k, Variant *&ret, bool copy,
bool checkExist) {
assert(IsValidKey(k));
TypedValueAccessor tvk = k.getTypedAccessor();
return isIntKey(tvk) ? lval(getIntKey(tvk), ret, copy, checkExist) :
lval(getStringKey(tvk), ret, copy, checkExist);
}
inline ArrayData *ArrayData::lvalPtr(CStrRef k, Variant *&ret, bool copy,
bool create) {
assert(IsValidKey(k));
return lvalPtr(k.get(), ret, copy, create);
}
inline ArrayData* ArrayData::set(CStrRef k, CVarRef v, bool copy) {
assert(IsValidKey(k));
return set(k.get(), v, copy);
}
inline ArrayData* ArrayData::set(CVarRef k, CVarRef v, bool copy) {
assert(IsValidKey(k));
TypedValueAccessor tvk = k.getTypedAccessor();
return isIntKey(tvk) ? set(getIntKey(tvk), v, copy) :
set(getStringKey(tvk), v, copy);
}
inline ArrayData* ArrayData::nvSet(int64_t ki, const TypedValue* v, bool copy) {
return set(ki, tvAsCVarRef(v), copy);
}
inline ArrayData* ArrayData::nvSet(StringData* k, const TypedValue* v,
bool copy) {
return set(k, tvAsCVarRef(v), copy);
}
inline ArrayData* ArrayData::setRef(CStrRef k, CVarRef v, bool copy) {
assert(IsValidKey(k));
return setRef(k.get(), v, copy);
}
inline ArrayData* ArrayData::setRef(CVarRef k, CVarRef v, bool copy) {
assert(IsValidKey(k));
TypedValueAccessor tvk = k.getTypedAccessor();
return isIntKey(tvk) ? setRef(getIntKey(tvk), v, copy) :
setRef(getStringKey(tvk), v, copy);
}
inline ArrayData* ArrayData::add(CStrRef k, CVarRef v, bool copy) {
assert(IsValidKey(k));
return add(k.get(), v, copy);
}
inline ArrayData* ArrayData::add(CVarRef k, CVarRef v, bool copy) {
assert(IsValidKey(k));
TypedValueAccessor tvk = k.getTypedAccessor();
return isIntKey(tvk) ? add(getIntKey(tvk), v, copy) :
add(getStringKey(tvk), v, copy);
}
inline ArrayData* ArrayData::addLval(CStrRef k, Variant *&ret, bool copy) {
assert(IsValidKey(k));
return addLval(k.get(), ret, copy);
}
inline ArrayData* ArrayData::addLval(CVarRef k, Variant *&ret, bool copy) {
assert(IsValidKey(k));
TypedValueAccessor tvk = k.getTypedAccessor();
return isIntKey(tvk) ? addLval(getIntKey(tvk), ret, copy) :
addLval(getStringKey(tvk), ret, copy);
}
inline ArrayData* ArrayData::remove(CStrRef k, bool copy) {
assert(IsValidKey(k));
return remove(k.get(), copy);
}
inline ArrayData* ArrayData::remove(CVarRef k, bool copy) {
assert(IsValidKey(k));
TypedValueAccessor tvk = k.getTypedAccessor();
return isIntKey(tvk) ? remove(getIntKey(tvk), copy) :
remove(getStringKey(tvk), copy);
}
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_ARRAY_INLINE_H_