diff options
| author | Michael Dusan <michael.dusan@gmail.com> | 2020-02-10 21:08:08 -0500 |
|---|---|---|
| committer | Michael Dusan <michael.dusan@gmail.com> | 2020-02-10 21:08:08 -0500 |
| commit | edb210905dcbe666fa5222bceacd2e5bdb16bb89 (patch) | |
| tree | 984aec0e5bad756daf426855c54bae3c42c73eca /src/mem_type_info.hpp | |
| parent | 1cdefeb10b7496126bbb7d00709235abfee56a4a (diff) | |
| download | zig-edb210905dcbe666fa5222bceacd2e5bdb16bb89.tar.gz zig-edb210905dcbe666fa5222bceacd2e5bdb16bb89.zip | |
stage1: memory/report overhaul
- split util_base.hpp from util.hpp
- new namespaces: `mem` and `heap`
- new `mem::Allocator` interface
- new `heap::CAllocator` impl with global `heap::c_allocator`
- new `heap::ArenaAllocator` impl
- new `mem::TypeInfo` extracts names without RTTI
- name extraction is enabled w/ ZIG_ENABLE_MEM_PROFILE=1
- new `mem::List` takes explicit `Allocator&` parameter
- new `mem::HashMap` takes explicit `Allocator&` parameter
- add Codegen.pass1_arena and use for all `ZigValue` allocs
- deinit Codegen.pass1_arena early in `zig_llvm_emit_output()`
Diffstat (limited to 'src/mem_type_info.hpp')
| -rw-r--r-- | src/mem_type_info.hpp | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/src/mem_type_info.hpp b/src/mem_type_info.hpp new file mode 100644 index 0000000000..8698992ca0 --- /dev/null +++ b/src/mem_type_info.hpp @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2020 Andrew Kelley + * + * This file is part of zig, which is MIT licensed. + * See http://opensource.org/licenses/MIT + */ + +#ifndef ZIG_MEM_TYPE_INFO_HPP +#define ZIG_MEM_TYPE_INFO_HPP + +#include "config.h" + +#ifndef ZIG_TYPE_INFO_IMPLEMENTATION +# ifdef ZIG_ENABLE_MEM_PROFILE +# define ZIG_TYPE_INFO_IMPLEMENTATION 1 +# else +# define ZIG_TYPE_INFO_IMPLEMENTATION 0 +# endif +#endif + +namespace mem { + +#if ZIG_TYPE_INFO_IMPLEMENTATION == 0 + +struct TypeInfo { + size_t size; + size_t alignment; + + template <typename T> + static constexpr TypeInfo make() { + return {sizeof(T), alignof(T)}; + } +}; + +#elif ZIG_TYPE_INFO_IMPLEMENTATION == 1 + +// +// A non-portable way to get a human-readable type-name compatible with +// non-RTTI C++ compiler mode; eg. `-fno-rtti`. +// +// Minimum requirements are c++11 and a compiler that has a constant for the +// current function's decorated name whereby a template-type name can be +// computed. eg. `__PRETTY_FUNCTION__` or `__FUNCSIG__`. +// +// given the following snippet: +// +// | #include <stdio.h> +// | +// | struct Top {}; +// | namespace mynamespace { +// | using custom = unsigned int; +// | struct Foo { +// | struct Bar {}; +// | }; +// | }; +// | +// | template <typename T> +// | void foobar() { +// | #ifdef _MSC_VER +// | fprintf(stderr, "--> %s\n", __FUNCSIG__); +// | #else +// | fprintf(stderr, "--> %s\n", __PRETTY_FUNCTION__); +// | #endif +// | } +// | +// | int main() { +// | foobar<Top>(); +// | foobar<unsigned int>(); +// | foobar<mynamespace::custom>(); +// | foobar<mynamespace::Foo*>(); +// | foobar<mynamespace::Foo::Bar*>(); +// | } +// +// gcc 9.2.0 produces: +// --> void foobar() [with T = Top] +// --> void foobar() [with T = unsigned int] +// --> void foobar() [with T = unsigned int] +// --> void foobar() [with T = mynamespace::Foo*] +// --> void foobar() [with T = mynamespace::Foo::Bar*] +// +// xcode 11.3.1/clang produces: +// --> void foobar() [T = Top] +// --> void foobar() [T = unsigned int] +// --> void foobar() [T = unsigned int] +// --> void foobar() [T = mynamespace::Foo *] +// --> void foobar() [T = mynamespace::Foo::Bar *] +// +// VStudio 2019 16.5.0/msvc produces: +// --> void __cdecl foobar<struct Top>(void) +// --> void __cdecl foobar<unsigned int>(void) +// --> void __cdecl foobar<unsigned int>(void) +// --> void __cdecl foobar<structmynamespace::Foo*>(void) +// --> void __cdecl foobar<structmynamespace::Foo::Bar*>(void) +// +struct TypeInfo { + const char *name_ptr; + size_t name_len; + size_t size; + size_t alignment; + + static constexpr TypeInfo to_type_info(const char *str, size_t start, size_t end, size_t size, size_t alignment) { + return TypeInfo{str + start, end - start, size, alignment}; + } + + static constexpr size_t index_of(const char *str, char c) { + return *str == c ? 0 : 1 + index_of(str + 1, c); + } + + template <typename T> + static constexpr const char *decorated_name() { +#ifdef _MSC_VER + return __FUNCSIG__; +#else + return __PRETTY_FUNCTION__; +#endif + } + + static constexpr TypeInfo extract(const char *decorated, size_t size, size_t alignment) { +#ifdef _MSC_VER + return to_type_info(decorated, index_of(decorated, '<') + 1, index_of(decorated, '>'), size, alignment); +#else + return to_type_info(decorated, index_of(decorated, '=') + 2, index_of(decorated, ']'), size, alignment); +#endif + } + + template <typename T> + static constexpr TypeInfo make() { + return TypeInfo::extract(TypeInfo::decorated_name<T>(), sizeof(T), alignof(T)); + } +}; + +#endif // ZIG_TYPE_INFO_IMPLEMENTATION + +} // namespace mem + +#endif |
