Skip to content

Commit

Permalink
Pass the pointer of owning object in GCPointer::set() part I (#1502)
Browse files Browse the repository at this point in the history
Summary: Pull Request resolved: #1502

Differential Revision: D62222257
  • Loading branch information
lavenzg authored and facebook-github-bot committed Nov 21, 2024
1 parent 485c0df commit 02dfb5c
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 14 deletions.
32 changes: 22 additions & 10 deletions include/hermes/VM/GCPointer-inline.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,33 @@ GCPointerBase::GCPointerBase(
}
}

inline void GCPointerBase::set(PointerBase &base, GCCell *ptr, GC &gc) {
template <
GCPointerBase::MaybeLargeObj maybeLargeObj,
GCPointerBase::NonNull nonNull>
inline void GCPointerBase::setImpl(
PointerBase &base,
GCCell *ptr,
GC &gc,
const GCCell *owningObj) {
assert(
(!ptr || gc.validPointer(ptr)) &&
"Cannot set a GCPointer to an invalid pointer");
// Write barrier must happen before the write.
gc.writeBarrier(this, ptr);
setNoBarrier(CompressedPointer::encode(ptr, base));
}
(void)owningObj;
if constexpr (maybeLargeObj == MaybeLargeObj::Yes) {
assert(
owningObj &&
"The cell pointer must be provided for cell kind that supports large allocation");

inline void GCPointerBase::setNonNull(PointerBase &base, GCCell *ptr, GC &gc) {
assert(
gc.validPointer(ptr) && "Cannot set a GCPointer to an invalid pointer");
// Write barrier must happen before the write.
gc.writeBarrier(this, ptr);
setNoBarrier(CompressedPointer::encodeNonNull(ptr, base));
gc.writeBarrier(this, ptr);
} else {
gc.writeBarrier(this, ptr);
}
if constexpr (nonNull == NonNull::Yes) {
setNoBarrier(CompressedPointer::encodeNonNull(ptr, base));
} else {
setNoBarrier(CompressedPointer::encode(ptr, base));
}
}

inline void
Expand Down
51 changes: 47 additions & 4 deletions include/hermes/VM/GCPointer.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,47 @@ class GCPointerBase : public CompressedPointer {
class NoBarriers : public std::false_type {};
class YesBarriers : public std::true_type {};

/// This must be used to assign a new value to this GCPointer.
/// This must be used to assign a new value to this GCPointer. This must not
/// be used if it lives in an object that supports large allocation.
/// \param ptr The memory being pointed to.
/// \param base The base of ptr.
/// \param gc Used for write barriers.
inline void set(PointerBase &base, GCCell *ptr, GC &gc);
inline void set(PointerBase &base, GCCell *ptr, GC &gc) {
setImpl<MaybeLargeObj::No, NonNull::No>(base, ptr, gc, nullptr);
}
inline void set(PointerBase &base, CompressedPointer ptr, GC &gc);
inline void setNonNull(PointerBase &base, GCCell *ptr, GC &gc);
inline void setNonNull(PointerBase &base, GCCell *ptr, GC &gc) {
setImpl<MaybeLargeObj::No, NonNull::Yes>(base, ptr, gc, nullptr);
}

/// This must be used to assign a new value to this GCPointer.
/// \param ptr The memory being pointed to.
/// \param base The base of ptr.
/// \param gc Used for write barriers.
/// \param owningObj The object that contains this GCPointer, used by the
/// writer barriers.
inline void
set(PointerBase &base, GCCell *ptr, GC &gc, const GCCell *owningObj) {
setImpl<MaybeLargeObj::Yes, NonNull::No>(base, ptr, gc, owningObj);
}
inline void
setNonNull(PointerBase &base, GCCell *ptr, GC &gc, const GCCell *owningObj) {
setImpl<MaybeLargeObj::Yes, NonNull::Yes>(base, ptr, gc, owningObj);
}

/// Set this pointer to null. This needs a write barrier in some types of
/// garbage collectors.
inline void setNull(GC &gc);

private:
enum class MaybeLargeObj { No = 0, Yes };
enum class NonNull { No = 0, Yes };
/// Implementation details shared by all set* functions here.
/// \tparam maybeLargeObj Whether the owning object supports large allocation.
/// If it is false, \p owningObj is not used by the writer barriers.
/// \tparam nonNull Whether \p is non null.
template <MaybeLargeObj maybeLargeObj, NonNull nonNull>
void setImpl(PointerBase &base, GCCell *ptr, GC &gc, const GCCell *owningObj);
};

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

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

/// Assign a new value to this GCPointer.
/// \param ptr The memory being pointed to.
/// \param gc Used for write barriers.
/// \param owningObj The object that contains this GCPointer, used by the
/// writer barriers.
void set(PointerBase &base, T *ptr, GC &gc, const GCCell *owningObj) {
GCPointerBase::set(base, ptr, gc, owningObj);
}
void setNonNull(PointerBase &base, T *ptr, GC &gc, const GCCell *owningObj) {
GCPointerBase::setNonNull(base, ptr, gc, owningObj);
}

/// Convenience overload of GCPointer::set for other GCPointers.
void set(PointerBase &base, const GCPointer<T> &ptr, GC &gc) {
GCPointerBase::set(base, ptr, gc);
Expand Down

0 comments on commit 02dfb5c

Please sign in to comment.