summaryrefslogtreecommitdiffstats
path: root/runtime/base/scoped_arena_containers.h
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2015-10-15 17:47:48 -0700
committerMathieu Chartier <mathieuc@google.com>2015-10-23 13:26:55 -0700
commit7b05e17db15879b486f3299a9a41ac17b87700f4 (patch)
treecf131b61e127f91c414954cc3ab038aa498a6018 /runtime/base/scoped_arena_containers.h
parent92ca333976cf381de004945f95fa1e347d0a3a0e (diff)
downloadart-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.h34
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_