diff options
author | Mathieu Chartier <mathieuc@google.com> | 2015-10-15 17:47:48 -0700 |
---|---|---|
committer | Mathieu Chartier <mathieuc@google.com> | 2015-10-23 13:26:55 -0700 |
commit | 7b05e17db15879b486f3299a9a41ac17b87700f4 (patch) | |
tree | cf131b61e127f91c414954cc3ab038aa498a6018 /runtime/base/scoped_arena_containers.h | |
parent | 92ca333976cf381de004945f95fa1e347d0a3a0e (diff) | |
download | art-7b05e17db15879b486f3299a9a41ac17b87700f4.tar.gz art-7b05e17db15879b486f3299a9a41ac17b87700f4.tar.bz2 art-7b05e17db15879b486f3299a9a41ac17b87700f4.zip |
Add ArenaUniquePtr
Motivation is to use it for adding arenas in the verifier.
Also added arena tags to prevent double free errors.
Bug: 10921004
Change-Id: I545f3374eceb9a6a35e738cb899d1493098fb760
Diffstat (limited to 'runtime/base/scoped_arena_containers.h')
-rw-r--r-- | runtime/base/scoped_arena_containers.h | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/runtime/base/scoped_arena_containers.h b/runtime/base/scoped_arena_containers.h index 562c2bf01c..b74aef184f 100644 --- a/runtime/base/scoped_arena_containers.h +++ b/runtime/base/scoped_arena_containers.h @@ -196,6 +196,40 @@ inline ScopedArenaAllocatorAdapter<void> ScopedArenaAllocator::Adapter(ArenaAllo return ScopedArenaAllocatorAdapter<void>(this, kind); } +// Special deleter that only calls the destructor. Also checks for double free errors. +template <typename T> +class ArenaDelete { + static constexpr uint8_t kMagicFill = 0xCE; + public: + void operator()(T* ptr) const { + ptr->~T(); + if (RUNNING_ON_MEMORY_TOOL > 0) { + // Writing to the memory will fail if it we already destroyed the pointer with + // DestroyOnlyDelete since we make it no access. + memset(ptr, kMagicFill, sizeof(T)); + MEMORY_TOOL_MAKE_NOACCESS(ptr, sizeof(T)); + } else if (kIsDebugBuild) { + CHECK(ArenaStack::ArenaTagForAllocation(reinterpret_cast<void*>(ptr)) == ArenaFreeTag::kUsed) + << "Freeing invalid object " << ptr; + ArenaStack::ArenaTagForAllocation(reinterpret_cast<void*>(ptr)) = ArenaFreeTag::kFree; + // Write a magic value to try and catch use after free error. + memset(ptr, kMagicFill, sizeof(T)); + } + } +}; + +// Declare but do not define a partial specialization for T[]. +// This is to prevent accidental use of this unsupported use case. +template <typename T> +class ArenaDelete<T[]> { + public: + void operator()(T* ptr) const = delete; +}; + +// Arena unique ptr that only calls the destructor of the element. +template <typename T> +using ArenaUniquePtr = std::unique_ptr<T, ArenaDelete<T>>; + } // namespace art #endif // ART_RUNTIME_BASE_SCOPED_ARENA_CONTAINERS_H_ |