Skip to content

Commit

Permalink
Add type confusion protection to the default memory provider.
Browse files Browse the repository at this point in the history
  • Loading branch information
davidchisnall committed Aug 13, 2019
1 parent 6dbe24d commit d56201e
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 14 deletions.
19 changes: 19 additions & 0 deletions src/ds/helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
13 changes: 3 additions & 10 deletions src/mem/alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ namespace snmalloc
* variable. This should be used from within the library or program that
* 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
* two different types of pagemap then they will see two distinct pagemaps.
* This will prevent allocating with one and freeing with the other (because
Expand All @@ -69,21 +69,14 @@ namespace snmalloc
* having two different types.
*/
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.
*/
static SuperslabPagemap& pagemap()
{
return global_pagemap;
return TypedSingleton<SuperslabPagemap>::global;
}
};

Expand Down
2 changes: 1 addition & 1 deletion src/mem/globalalloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ namespace snmalloc

static AllocPool* make() noexcept
{
return make(default_memory_provider);
return AllocPool::make(default_memory_provider());
}

Alloc* acquire()
Expand Down
5 changes: 4 additions & 1 deletion src/mem/largealloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -405,5 +405,8 @@ namespace snmalloc
* The memory provider that will be used if no other provider is explicitly
* passed as an argument.
*/
inline GlobalVirtual default_memory_provider;
inline GlobalVirtual& default_memory_provider()
{
return TypedSingleton<GlobalVirtual>::global;
}
} // namespace snmalloc
2 changes: 1 addition & 1 deletion src/mem/pagemap.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ namespace snmalloc
if (e->compare_exchange_strong(
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>();
e->store(value, std::memory_order_release);
}
Expand Down
2 changes: 1 addition & 1 deletion src/mem/threadalloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace snmalloc
* required. This avoids a branch on the fast path.
*/
inline Alloc GlobalPlaceHolder(
default_memory_provider, SNMALLOC_DEFAULT_PAGEMAP(), nullptr, true);
default_memory_provider(), SNMALLOC_DEFAULT_PAGEMAP(), nullptr, true);

#ifdef SNMALLOC_EXTERNAL_THREAD_ALLOC
/**
Expand Down

0 comments on commit d56201e

Please sign in to comment.