Skip to content

Commit 65d3797

Browse files
lavenzgfacebook-github-bot
authored andcommitted
Pass the pointer of owning object in GCPointer::set() part I (facebook#1502)
Summary: Pull Request resolved: facebook#1502 Differential Revision: D62222257
1 parent 858949f commit 65d3797

File tree

2 files changed

+65
-14
lines changed

2 files changed

+65
-14
lines changed

include/hermes/VM/GCPointer-inline.h

+20-10
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,31 @@ GCPointerBase::GCPointerBase(
3232
}
3333
}
3434

35-
inline void GCPointerBase::set(PointerBase &base, GCCell *ptr, GC &gc) {
35+
template <typename MaybeLargeObj, typename NonNull>
36+
inline void GCPointerBase::setImpl(
37+
PointerBase &base,
38+
GCCell *ptr,
39+
GC &gc,
40+
const GCCell *owningObj) {
3641
assert(
3742
(!ptr || gc.validPointer(ptr)) &&
3843
"Cannot set a GCPointer to an invalid pointer");
3944
// Write barrier must happen before the write.
40-
gc.writeBarrier(this, ptr);
41-
setNoBarrier(CompressedPointer::encode(ptr, base));
42-
}
45+
(void)owningObj;
46+
if constexpr (MaybeLargeObj::value) {
47+
assert(
48+
owningObj &&
49+
"The cell pointer must be provided for cell kind that supports large allocation");
4350

44-
inline void GCPointerBase::setNonNull(PointerBase &base, GCCell *ptr, GC &gc) {
45-
assert(
46-
gc.validPointer(ptr) && "Cannot set a GCPointer to an invalid pointer");
47-
// Write barrier must happen before the write.
48-
gc.writeBarrier(this, ptr);
49-
setNoBarrier(CompressedPointer::encodeNonNull(ptr, base));
51+
gc.writeBarrier(this, ptr);
52+
} else {
53+
gc.writeBarrier(this, ptr);
54+
}
55+
if constexpr (NonNull::value) {
56+
setNoBarrier(CompressedPointer::encodeNonNull(ptr, base));
57+
} else {
58+
setNoBarrier(CompressedPointer::encode(ptr, base));
59+
}
5060
}
5161

5262
inline void

include/hermes/VM/GCPointer.h

+45-4
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,45 @@ class GCPointerBase : public CompressedPointer {
3434
class NoBarriers : public std::false_type {};
3535
class YesBarriers : public std::true_type {};
3636

37-
/// This must be used to assign a new value to this GCPointer.
37+
/// This must be used to assign a new value to this GCPointer. This must not
38+
/// be used if it lives in an object that supports large allocation.
3839
/// \param ptr The memory being pointed to.
3940
/// \param base The base of ptr.
4041
/// \param gc Used for write barriers.
41-
inline void set(PointerBase &base, GCCell *ptr, GC &gc);
42+
inline void set(PointerBase &base, GCCell *ptr, GC &gc) {
43+
setImpl<std::false_type, std::false_type>(base, ptr, gc, nullptr);
44+
}
4245
inline void set(PointerBase &base, CompressedPointer ptr, GC &gc);
43-
inline void setNonNull(PointerBase &base, GCCell *ptr, GC &gc);
46+
inline void setNonNull(PointerBase &base, GCCell *ptr, GC &gc) {
47+
setImpl<std::false_type, std::true_type>(base, ptr, gc, nullptr);
48+
}
49+
50+
/// This must be used to assign a new value to this GCPointer.
51+
/// \param ptr The memory being pointed to.
52+
/// \param base The base of ptr.
53+
/// \param gc Used for write barriers.
54+
/// \param owningObj The object that contains this GCPointer, used by the
55+
/// writer barriers.
56+
inline void
57+
set(PointerBase &base, GCCell *ptr, GC &gc, const GCCell *owningObj) {
58+
setImpl<std::true_type, std::false_type>(base, ptr, gc, owningObj);
59+
}
60+
inline void
61+
setNonNull(PointerBase &base, GCCell *ptr, GC &gc, const GCCell *owningObj) {
62+
setImpl<std::true_type, std::true_type>(base, ptr, gc, owningObj);
63+
}
4464

4565
/// Set this pointer to null. This needs a write barrier in some types of
4666
/// garbage collectors.
4767
inline void setNull(GC &gc);
68+
69+
private:
70+
/// Implementation details shared by all set* functions here.
71+
/// \tparam MaybeLargeObj Whether the owning object supports large allocation.
72+
/// If it is false, \p owningObj is not used by the writer barriers.
73+
/// \tparam NonNull Whether \p is non null.
74+
template <typename MaybeLargeObj, typename NonNull>
75+
void setImpl(PointerBase &base, GCCell *ptr, GC &gc, const GCCell *owningObj);
4876
};
4977

5078
/// A class to represent "raw" pointers to heap objects. Disallows assignment,
@@ -86,7 +114,8 @@ class GCPointer : public GCPointerBase {
86114
return vmcast<T>(GCPointerBase::getNonNull(base));
87115
}
88116

89-
/// Assign a new value to this GCPointer.
117+
/// Assign a new value to this GCPointer. This must not be used if it lives in
118+
/// an object that supports large allocation.
90119
/// \param base The base of ptr.
91120
/// \param ptr The memory being pointed to.
92121
/// \param gc Used for write barriers.
@@ -97,6 +126,18 @@ class GCPointer : public GCPointerBase {
97126
GCPointerBase::setNonNull(base, ptr, gc);
98127
}
99128

129+
/// Assign a new value to this GCPointer.
130+
/// \param ptr The memory being pointed to.
131+
/// \param gc Used for write barriers.
132+
/// \param owningObj The object that contains this GCPointer, used by the
133+
/// writer barriers.
134+
void set(PointerBase &base, T *ptr, GC &gc, const GCCell *owningObj) {
135+
GCPointerBase::set(base, ptr, gc, owningObj);
136+
}
137+
void setNonNull(PointerBase &base, T *ptr, GC &gc, const GCCell *owningObj) {
138+
GCPointerBase::setNonNull(base, ptr, gc, owningObj);
139+
}
140+
100141
/// Convenience overload of GCPointer::set for other GCPointers.
101142
void set(PointerBase &base, const GCPointer<T> &ptr, GC &gc) {
102143
GCPointerBase::set(base, ptr, gc);

0 commit comments

Comments
 (0)