Attribute ETEWH result array provenance better
[hiphop-php.git] / hphp / runtime / base / array-provenance.h
blob26989258d158fb6ceaff5253fe454831a8158df0
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_ARRAY_PROVENANCE_H
18 #define incl_HPHP_ARRAY_PROVENANCE_H
20 #include "hphp/runtime/base/runtime-option.h"
21 #include "hphp/runtime/base/typed-value.h"
22 #include "hphp/runtime/base/types.h"
24 #include "hphp/util/low-ptr.h"
25 #include "hphp/util/rds-local.h"
27 #include <folly/Format.h>
28 #include <folly/Optional.h>
30 namespace HPHP {
32 struct APCArray;
33 struct ArrayData;
34 struct StringData;
35 struct c_WaitableWaitHandle;
37 namespace arrprov {
39 ///////////////////////////////////////////////////////////////////////////////
42 * A provenance annotation
44 * We need to store the filename and line since when assembling units, we
45 * don't necessarily have the final Unit allocated yet. It may be faster to
46 * make this a tagged union or store a different Tag type for static arrays
48 struct Tag {
49 Tag() = default;
50 Tag(const StringData* filename, int line)
51 : m_filename(filename)
52 , m_line(line) {
53 assertx(m_filename);
56 const StringData* filename() const { return m_filename; }
57 int line() const { return m_line; }
59 bool operator==(const Tag& other) const {
60 return m_filename == other.m_filename &&
61 m_line == other.m_line;
63 bool operator!=(const Tag& other) const { return !(*this == other); }
65 std::string toString() const;
67 private:
68 const StringData* m_filename{nullptr};
69 int m_line{0};
73 * This is a separate struct so it can live in RDS and not be GC scanned--the
74 * actual RDS-local handle is kept in the implementation
76 struct ArrayProvenanceTable {
77 /* The table itself -- allocated in general heap */
78 folly::F14FastMap<const void*, Tag> tags;
81 * We never dereference ArrayData*s from this table--so it's safe for the GC
82 * to ignore them in this table
84 TYPE_SCAN_IGNORE_FIELD(tags);
87 ///////////////////////////////////////////////////////////////////////////////
90 * Create a tag based on the current PC and unit.
92 * Attempts to sync VM regs and returns folly::none on failure.
94 folly::Optional<Tag> tagFromPC();
97 * RAII struct for modifying the behavior of tagFromPC().
99 * When this is in effect, we backtrace from `wh` instead of vmfp().
101 struct TagOverride {
102 explicit TagOverride(c_WaitableWaitHandle* wh);
103 ~TagOverride();
105 private:
106 c_WaitableWaitHandle* m_saved_wh;
110 * Whether `a` or `tv` admits a provenance tag---i.e., whether it's either a
111 * vec or a dict.
113 bool arrayWantsTag(const ArrayData* a);
114 bool arrayWantsTag(const APCArray* a);
115 bool tvWantsTag(TypedValue tv);
118 * Get the provenance tag for `a`.
120 folly::Optional<Tag> getTag(const ArrayData* a);
121 folly::Optional<Tag> getTag(const APCArray* a);
124 * Set mode: insert or emplace.
126 * Just controls whether we assert about provenance not already being set: we
127 * assert for Insert mode, and not for Emplace.
129 enum class Mode { Insert, Emplace };
132 * Set the provenance tag for `a` to `tag`.
134 template<Mode mode = Mode::Insert> void setTag(ArrayData* a, Tag tag);
135 template<Mode mode = Mode::Insert> void setTag(const APCArray* a, Tag tag);
138 * Clear a tag for a released array---only call this if the array is henceforth
139 * unreachable or no longer of a kind that accepts provenance tags
141 void clearTag(ArrayData* ad);
142 void clearTag(const APCArray* a);
145 * Tag `tv` with provenance for the current PC and unit (if it admits a tag and
146 * doesn't already have one).
148 * tagTV() takes logical ownership of `tv`, and if it makes any modifications,
149 * it will incref the new value and decref the old one. As such, generally the
150 * appropriate use of this function is:
152 * tv = tagTV(tv);
154 * without touching the usual TV mutation machinery.
156 TypedValue tagTV(TypedValue tv);
157 TypedValue tagTVKnown(TypedValue tv, Tag tag);
160 * Produce a static empty array with the given provenance tag.
162 * If no tag is provided, we attempt to make one from vmpc(), and failing that
163 * we just return the input array.
165 ArrayData* makeEmptyVec(folly::Optional<Tag> tag = folly::none);
166 ArrayData* makeEmptyDict(folly::Optional<Tag> tag = folly::none);
167 ArrayData* tagStaticArr(ArrayData* ad, folly::Optional<Tag> tag = folly::none);
169 ///////////////////////////////////////////////////////////////////////////////
173 #define incl_HPHP_ARRAY_PROVENANCE_INL_H_
174 #include "hphp/runtime/base/array-provenance-inl.h"
175 #undef incl_HPHP_ARRAY_PROVENANCE_INL_H_
177 #endif