From 7cb9788ba323448053f909e5dda86bd6a4f78442 Mon Sep 17 00:00:00 2001 From: Bin Liu Date: Mon, 17 May 2021 18:37:50 -0700 Subject: [PATCH] track static array in reverse data map Reviewed By: ottoni Differential Revision: D22850373 fbshipit-source-id: 9a0516f2d2df225f16d875fd5ecfe71a629e2386 --- hphp/runtime/base/array-data.cpp | 4 ++++ hphp/runtime/base/perf-mem-event.cpp | 4 ++++ hphp/runtime/vm/reverse-data-map.cpp | 12 ++++++++++++ hphp/runtime/vm/reverse-data-map.h | 4 ++++ 4 files changed, 24 insertions(+) diff --git a/hphp/runtime/base/array-data.cpp b/hphp/runtime/base/array-data.cpp index 39bd4640424..234e625aebe 100644 --- a/hphp/runtime/base/array-data.cpp +++ b/hphp/runtime/base/array-data.cpp @@ -35,6 +35,7 @@ #include "hphp/runtime/base/variable-serializer.h" #include "hphp/runtime/server/memory-stats.h" #include "hphp/runtime/vm/interp-helpers.h" +#include "hphp/runtime/vm/reverse-data-map.h" #include "hphp/util/exception.h" @@ -235,6 +236,9 @@ void ArrayData::GetScalarArray(ArrayData** parr) { // TODO(T68458896): allocSize rounds up to size class, which we shouldn't do. MemoryStats::LogAlloc(AllocKind::StaticArray, allocSize(ad)); + if (RuntimeOption::EvalEnableReverseDataMap) { + data_map::register_start(ad); + } s_cachedHash.first = ad; assertx(hashArrayPortion(ad) == s_cachedHash.second); diff --git a/hphp/runtime/base/perf-mem-event.cpp b/hphp/runtime/base/perf-mem-event.cpp index 92a4edcccd6..d87b4a9aec9 100644 --- a/hphp/runtime/base/perf-mem-event.cpp +++ b/hphp/runtime/base/perf-mem-event.cpp @@ -227,6 +227,10 @@ bool record_vm_metadata_mem_event(data_map::result res, const void* addr, assertx(!res.empty()); match( res, + [&](const ArrayData* arr) { + record.setInt("offset", pos - reinterpret_cast(arr)); + record.setStr("kind", "Array"); + }, [&](const Class* cls) { record.setInt("offset", pos - reinterpret_cast(cls)); record.setStr("kind", "Class"); diff --git a/hphp/runtime/vm/reverse-data-map.cpp b/hphp/runtime/vm/reverse-data-map.cpp index 9f1a789c2fb..d6a0d0d3d89 100644 --- a/hphp/runtime/vm/reverse-data-map.cpp +++ b/hphp/runtime/vm/reverse-data-map.cpp @@ -16,6 +16,9 @@ #include "hphp/runtime/vm/reverse-data-map.h" +#include "hphp/runtime/base/array-data.h" +#include "hphp/runtime/base/memory-manager-defs.h" +#include "hphp/runtime/base/packed-array-defs.h" #include "hphp/runtime/base/string-data.h" #include "hphp/runtime/vm/class.h" #include "hphp/runtime/vm/func.h" @@ -37,6 +40,7 @@ namespace { /////////////////////////////////////////////////////////////////////////////// #define META_TYPES \ + X(ArrayData)\ X(Class)\ X(Func)\ X(NamedEntity)\ @@ -50,6 +54,7 @@ enum class Kind : uint8_t { NamedEntity = 3, StringData = 4, Unit = 5, + ArrayData = 6, }; constexpr size_t kChunkSize = 1 << 21; @@ -111,6 +116,13 @@ void deregister(Kind /*kind*/, const void* meta) { * These routines account for variable-length prefix or suffix allocations, * such as Class's funcVec and classVec, or StringData's data(). */ +bool contains(const ArrayData* arr, const void* addr) { + auto const start = reinterpret_cast(arr); + if (addr < start) return false; + size_t heapSize = allocSize(arr); + return addr < start + heapSize; +} + bool contains(const Class* cls, const void* addr) { return cls->funcVec() <= addr && addr < cls->mallocEnd(); } diff --git a/hphp/runtime/vm/reverse-data-map.h b/hphp/runtime/vm/reverse-data-map.h index a54b0d5bad9..b10a1753c61 100644 --- a/hphp/runtime/vm/reverse-data-map.h +++ b/hphp/runtime/vm/reverse-data-map.h @@ -20,6 +20,7 @@ namespace HPHP { +struct ArrayData; struct Class; struct Func; struct NamedEntity; @@ -39,6 +40,7 @@ namespace data_map { * * The object pointer must be 16-byte aligned. */ +void register_start(const ArrayData*); void register_start(const Class*); void register_start(const Func*); void register_start(const NamedEntity*); @@ -51,6 +53,7 @@ void register_start(const Unit*); * Requires that register_start() was called on the object, and it has not yet * been deregistered. */ +void deregister(const ArrayData*); void deregister(const Class*); void deregister(const Func*); void deregister(const NamedEntity*); @@ -67,6 +70,7 @@ void deregister(const Unit*); * Returns an empty result if `addr' is not mapped. */ using result = folly::DiscriminatedPtr< + ArrayData, Class, Func, NamedEntity, -- 2.11.4.GIT