track total size of static array and Unit/Class/Func
[hiphop-php.git] / hphp / runtime / base / enum-cache.h
blob449b91a7763e546317d3e71dc53091ce67179841
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_ENUM_CACHE_H_
18 #define incl_HPHP_ENUM_CACHE_H_
20 #include "hphp/runtime/ext/extension.h"
21 #include "hphp/runtime/vm/class.h"
22 #include <tbb/concurrent_hash_map.h>
24 namespace HPHP {
26 //////////////////////////////////////////////////////////////////////
28 // Values in the TBB map that contain the enum static arrays
29 struct EnumValues {
30 // array from 'enum name' to 'enum value'
31 // e.g. [ 'RED' => 1, 'BLUE' =>2, ...]
32 Array values;
33 // array from 'enum value' to 'enum name'
34 // e.g. [ 1 => 'RED', 2 => 'BLUE', ...]
35 Array names;
38 struct EnumCache {
39 EnumCache() {}
40 ~EnumCache();
42 // TBB hash and compare struct
43 struct clsCompare {
44 bool equal(intptr_t key1, intptr_t key2) const {
45 assertx(key1 && key2);
46 bool equal = (key1 == key2);
47 assertx(!equal || getClass(key1)->name()->equal(getClass(key2)->name()));
48 return equal;
51 size_t hash(intptr_t key) const {
52 assertx(key);
53 return static_cast<size_t>(hash_int64(key));
57 // if the class provided derives from Enum the name/value and value/name
58 // arrays are build, stored in the cache and returned.
59 // If not an error is raised.
60 // If the recurse flag is 'true' array values are loaded up the hierarchy
61 // chain (if any).
62 static const EnumValues* getValues(const Class* klass, bool recurse);
63 // Like above, but for first-class enums
64 static const EnumValues* getValuesBuiltin(const Class* klass);
65 // Like above, but for first-class enums where the values can be computed
66 // entirely statically. Returns nullptr if that's not the case.
67 static const EnumValues* getValuesStatic(const Class* klass);
68 // delete the EnumValues element in the cache for the given class.
69 // If there is no entry this function is a no-op.
70 static void deleteValues(const Class* klass);
72 // Helper that raises a PHP exception
73 [[noreturn]] static void failLookup(const Variant& msg);
75 // Large enums get the dummy LargeEnum tag (so that we can cache a single
76 // static value for these enums). Small enums get a tag based on the caller.
77 static Array tagEnumWithProvenance(Array input);
79 private:
80 // Class* to intptr_ti key helpers
81 const static intptr_t RECURSE_MASK = 1;
82 static const Class* getClass(intptr_t key) {
83 return reinterpret_cast<const Class*>(key & ~RECURSE_MASK);
86 static intptr_t getKey(const Class* klass, bool recurse) {
87 intptr_t key = reinterpret_cast<intptr_t>(klass);
88 return (recurse) ? key | RECURSE_MASK : key;
91 const EnumValues* cachePersistentEnumValues(
92 const Class* klass,
93 bool recurse,
94 Array&& names,
95 Array&& values);
97 const EnumValues* cacheRequestEnumValues(
98 const Class* klass,
99 bool recurse,
100 Array&& names,
101 Array&& values);
103 const EnumValues* getEnumValuesIfDefined(intptr_t key,
104 bool checkLocal = true) const;
105 const EnumValues* getEnumValues(const Class* klass, bool recurse,
106 bool require_static = false);
107 const EnumValues* loadEnumValues(const Class* klass, bool recurse,
108 bool require_static = false);
109 void deleteEnumValues(intptr_t key);
111 // Map that contains associations between Enum classes and their array
112 // values and array names.
113 using EnumValuesMap = tbb::concurrent_hash_map<
114 intptr_t,
115 const EnumValues*,
116 clsCompare>;
118 using ReqEnumValuesMap = req::fast_map<
119 intptr_t,
120 const EnumValues*>;
122 // Persistent values, recursive case. Non-recursive are cached in Class.
123 EnumValuesMap m_enumValuesMap;
125 rds::Link<ReqEnumValuesMap*, rds::Mode::Normal> m_nonScalarEnumValuesMap;
128 //////////////////////////////////////////////////////////////////////
132 #endif