Add type confusion protection to the default memory provider.
This commit is contained in:
committed by
David Chisnall
parent
6dbe24da2e
commit
d56201e28d
@@ -42,6 +42,25 @@ namespace snmalloc
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A singleton global. Used to allow globals in headers. Precisely one
|
||||||
|
* instance of the static field will exist in the final program, irrespective
|
||||||
|
* of the number of compilation units that reference the field.
|
||||||
|
*
|
||||||
|
* C++ globals do not have their types as part of the name mangling, so this
|
||||||
|
* allows a singleton instance of a specific type that won't be confused with
|
||||||
|
* other template instantiations of the same type.
|
||||||
|
*/
|
||||||
|
template<class T>
|
||||||
|
struct TypedSingleton
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The global variable, which will have a mangled name that includes the
|
||||||
|
* type of `T`.
|
||||||
|
*/
|
||||||
|
static inline T global;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper for wrapping values.
|
* Wrapper for wrapping values.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ namespace snmalloc
|
|||||||
* variable. This should be used from within the library or program that
|
* variable. This should be used from within the library or program that
|
||||||
* owns the pagemap.
|
* owns the pagemap.
|
||||||
*
|
*
|
||||||
* This class makes the global pagemap a static field so that its name
|
* This class makes the global pagemap a typed singleton so that its name
|
||||||
* includes the type mangling. If two compilation units try to instantiate
|
* includes the type mangling. If two compilation units try to instantiate
|
||||||
* two different types of pagemap then they will see two distinct pagemaps.
|
* two different types of pagemap then they will see two distinct pagemaps.
|
||||||
* This will prevent allocating with one and freeing with the other (because
|
* This will prevent allocating with one and freeing with the other (because
|
||||||
@@ -69,21 +69,14 @@ namespace snmalloc
|
|||||||
* having two different types.
|
* having two different types.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class GlobalPagemapTemplate
|
struct GlobalPagemapTemplate
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* The global pagemap variable. The name of this symbol will include the
|
|
||||||
* type of `T`.
|
|
||||||
*/
|
|
||||||
inline static T global_pagemap;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
/**
|
||||||
* Returns the pagemap.
|
* Returns the pagemap.
|
||||||
*/
|
*/
|
||||||
static SuperslabPagemap& pagemap()
|
static SuperslabPagemap& pagemap()
|
||||||
{
|
{
|
||||||
return global_pagemap;
|
return TypedSingleton<SuperslabPagemap>::global;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ namespace snmalloc
|
|||||||
|
|
||||||
static AllocPool* make() noexcept
|
static AllocPool* make() noexcept
|
||||||
{
|
{
|
||||||
return make(default_memory_provider);
|
return AllocPool::make(default_memory_provider());
|
||||||
}
|
}
|
||||||
|
|
||||||
Alloc* acquire()
|
Alloc* acquire()
|
||||||
|
|||||||
@@ -405,5 +405,8 @@ namespace snmalloc
|
|||||||
* The memory provider that will be used if no other provider is explicitly
|
* The memory provider that will be used if no other provider is explicitly
|
||||||
* passed as an argument.
|
* passed as an argument.
|
||||||
*/
|
*/
|
||||||
inline GlobalVirtual default_memory_provider;
|
inline GlobalVirtual& default_memory_provider()
|
||||||
|
{
|
||||||
|
return TypedSingleton<GlobalVirtual>::global;
|
||||||
|
}
|
||||||
} // namespace snmalloc
|
} // namespace snmalloc
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ namespace snmalloc
|
|||||||
if (e->compare_exchange_strong(
|
if (e->compare_exchange_strong(
|
||||||
value, LOCKED_ENTRY, std::memory_order_relaxed))
|
value, LOCKED_ENTRY, std::memory_order_relaxed))
|
||||||
{
|
{
|
||||||
auto& v = default_memory_provider;
|
auto& v = default_memory_provider();
|
||||||
value = v.alloc_chunk<PagemapEntry, OS_PAGE_SIZE>();
|
value = v.alloc_chunk<PagemapEntry, OS_PAGE_SIZE>();
|
||||||
e->store(value, std::memory_order_release);
|
e->store(value, std::memory_order_release);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace snmalloc
|
|||||||
* required. This avoids a branch on the fast path.
|
* required. This avoids a branch on the fast path.
|
||||||
*/
|
*/
|
||||||
inline Alloc GlobalPlaceHolder(
|
inline Alloc GlobalPlaceHolder(
|
||||||
default_memory_provider, SNMALLOC_DEFAULT_PAGEMAP(), nullptr, true);
|
default_memory_provider(), SNMALLOC_DEFAULT_PAGEMAP(), nullptr, true);
|
||||||
|
|
||||||
#ifdef SNMALLOC_EXTERNAL_THREAD_ALLOC
|
#ifdef SNMALLOC_EXTERNAL_THREAD_ALLOC
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user