Skip to content

Commit 02dfb5c

Browse files
lavenzgfacebook-github-bot
authored andcommitted
Pass the pointer of owning object in GCPointer::set() part I (#1502)
Summary: Pull Request resolved: #1502 Differential Revision: D62222257
1 parent 485c0df commit 02dfb5c

File tree

2 files changed

+69
-14
lines changed

2 files changed

+69
-14
lines changed

include/hermes/VM/GCPointer-inline.h

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

35-
inline void GCPointerBase::set(PointerBase &base, GCCell *ptr, GC &gc) {
35+
template <
36+
GCPointerBase::MaybeLargeObj maybeLargeObj,
37+
GCPointerBase::NonNull nonNull>
38+
inline void GCPointerBase::setImpl(
39+
PointerBase &base,
40+
GCCell *ptr,
41+
GC &gc,
42+
const GCCell *owningObj) {
3643
assert(
3744
(!ptr || gc.validPointer(ptr)) &&
3845
"Cannot set a GCPointer to an invalid pointer");
3946
// Write barrier must happen before the write.
40-
gc.writeBarrier(this, ptr);
41-
setNoBarrier(CompressedPointer::encode(ptr, base));
42-
}
47+
(void)owningObj;
48+
if constexpr (maybeLargeObj == MaybeLargeObj::Yes) {
49+
assert(
50+
owningObj &&
51+
"The cell pointer must be provided for cell kind that supports large allocation");
4352

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));
53+
gc.writeBarrier(this, ptr);
54+
} else {
55+
gc.writeBarrier(this, ptr);
56+
}
57+
if constexpr (nonNull == NonNull::Yes) {
58+
setNoBarrier(CompressedPointer::encodeNonNull(ptr, base));
59+
} else {
60+
setNoBarrier(CompressedPointer::encode(ptr, base));
61+
}
5062
}
5163

5264
inline void

include/hermes/VM/GCPointer.h

+47-4
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,47 @@ 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<MaybeLargeObj::No, NonNull::No>(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<MaybeLargeObj::No, NonNull::Yes>(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<MaybeLargeObj::Yes, NonNull::No>(base, ptr, gc, owningObj);
59+
}
60+
inline void
61+
setNonNull(PointerBase &base, GCCell *ptr, GC &gc, const GCCell *owningObj) {
62+
setImpl<MaybeLargeObj::Yes, NonNull::Yes>(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+
enum class MaybeLargeObj { No = 0, Yes };
71+
enum class NonNull { No = 0, Yes };
72+
/// Implementation details shared by all set* functions here.
73+
/// \tparam maybeLargeObj Whether the owning object supports large allocation.
74+
/// If it is false, \p owningObj is not used by the writer barriers.
75+
/// \tparam nonNull Whether \p is non null.
76+
template <MaybeLargeObj maybeLargeObj, NonNull nonNull>
77+
void setImpl(PointerBase &base, GCCell *ptr, GC &gc, const GCCell *owningObj);
4878
};
4979

5080
/// A class to represent "raw" pointers to heap objects. Disallows assignment,
@@ -86,7 +116,8 @@ class GCPointer : public GCPointerBase {
86116
return vmcast<T>(GCPointerBase::getNonNull(base));
87117
}
88118

89-
/// Assign a new value to this GCPointer.
119+
/// Assign a new value to this GCPointer. This must not be used if it lives in
120+
/// an object that supports large allocation.
90121
/// \param base The base of ptr.
91122
/// \param ptr The memory being pointed to.
92123
/// \param gc Used for write barriers.
@@ -97,6 +128,18 @@ class GCPointer : public GCPointerBase {
97128
GCPointerBase::setNonNull(base, ptr, gc);
98129
}
99130

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

0 commit comments

Comments
 (0)