2 +----------------------------------------------------------------------+
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>
35 struct c_WaitableWaitHandle
;
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
50 Tag(const StringData
* filename
, int line
)
51 : m_filename(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;
68 const StringData
* m_filename
{nullptr};
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().
102 explicit TagOverride(c_WaitableWaitHandle
* wh
);
106 c_WaitableWaitHandle
* m_saved_wh
;
110 * Whether `a` or `tv` admits a provenance tag---i.e., whether it's either a
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:
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_