summaryrefslogtreecommitdiff
path: root/js/public
diff options
context:
space:
mode:
authorMoonchild <moonchild@palemoon.org>2020-08-03 09:41:42 +0000
committerMoonchild <moonchild@palemoon.org>2020-08-06 18:31:58 +0000
commite1e535c1c6372f95b4a14b6a00b6d6e7be400c3b (patch)
tree1e0cda7c9382d4f3fa8da42eb3ea5cf219572b0f /js/public
parent9b6252893876995ae4c1f278fc8d1cbdfb72e94d (diff)
downloaduxp-e1e535c1c6372f95b4a14b6a00b6d6e7be400c3b.tar.gz
[js] Try to catch bad pointers for GC and bail if not valid.
Diffstat (limited to 'js/public')
-rw-r--r--js/public/HeapAPI.h37
1 files changed, 37 insertions, 0 deletions
diff --git a/js/public/HeapAPI.h b/js/public/HeapAPI.h
index fef6c0c780..d033d3706e 100644
--- a/js/public/HeapAPI.h
+++ b/js/public/HeapAPI.h
@@ -51,6 +51,7 @@ const size_t ChunkMarkBitmapBits = 129024;
const size_t ChunkRuntimeOffset = ChunkSize - sizeof(void*);
const size_t ChunkTrailerSize = 2 * sizeof(uintptr_t) + sizeof(uint64_t);
const size_t ChunkLocationOffset = ChunkSize - ChunkTrailerSize;
+const size_t ChunkStoreBufferOffset = ChunkSize - ChunkTrailerSize + sizeof(uint64_t);
const size_t ArenaZoneOffset = sizeof(size_t);
const size_t ArenaHeaderSize = sizeof(size_t) + 2 * sizeof(uintptr_t) +
sizeof(size_t) + sizeof(uintptr_t);
@@ -326,6 +327,20 @@ CellIsMarkedGray(const Cell* cell)
extern JS_PUBLIC_API(bool)
CellIsMarkedGrayIfKnown(const Cell* cell);
+MOZ_ALWAYS_INLINE ChunkLocation GetCellLocation(const void* cell) {
+ uintptr_t addr = uintptr_t(cell);
+ addr &= ~js::gc::ChunkMask;
+ addr |= js::gc::ChunkLocationOffset;
+ return *reinterpret_cast<ChunkLocation*>(addr);
+}
+
+MOZ_ALWAYS_INLINE bool NurseryCellHasStoreBuffer(const void* cell) {
+ uintptr_t addr = uintptr_t(cell);
+ addr &= ~js::gc::ChunkMask;
+ addr |= js::gc::ChunkStoreBufferOffset;
+ return *reinterpret_cast<void**>(addr) != nullptr;
+}
+
} /* namespace detail */
MOZ_ALWAYS_INLINE bool
@@ -341,6 +356,28 @@ IsInsideNursery(const js::gc::Cell* cell)
return location == ChunkLocation::Nursery;
}
+MOZ_ALWAYS_INLINE bool IsCellPointerValid(const void* cell) {
+ auto addr = uintptr_t(cell);
+ if (addr < ChunkSize || addr % CellSize != 0) {
+ return false;
+ }
+ auto location = detail::GetCellLocation(cell);
+ if (location == ChunkLocation::TenuredHeap) {
+ return !!detail::GetGCThingZone(addr);
+ }
+ if (location == ChunkLocation::Nursery) {
+ return detail::NurseryCellHasStoreBuffer(cell);
+ }
+ return false;
+}
+
+MOZ_ALWAYS_INLINE bool IsCellPointerValidOrNull(const void* cell) {
+ if (!cell) {
+ return true;
+ }
+ return IsCellPointerValid(cell);
+}
+
} /* namespace gc */
} /* namespace js */