Skip to content

Commit e53ce80

Browse files
committed
fix Global allocator dyn dispatch on windows
1 parent dc20ccb commit e53ce80

4 files changed

Lines changed: 118 additions & 0 deletions

File tree

‎src/alloc/src/alloc.cppm‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,23 @@ struct rstd::Impl<rstd::alloc::Allocator, alloc_::Global>
132132
void deallocate(void* ptr, Layout layout) const noexcept {
133133
if (layout.size != usize()) ::alloc::dealloc(ptr, layout.cpp_layout());
134134
}
135+
136+
// Inherited member pointers in Global's dyn vtable crash Windows Clang with reduced BMIs.
137+
auto grow(void* pointer, Layout old_layout, Layout new_layout) const
138+
-> Result<Allocation, AllocError> {
139+
return DefaultInImpl<Allocator, alloc_::Global>::grow(pointer, old_layout, new_layout);
140+
}
141+
142+
auto grow_zeroed(void* pointer, Layout old_layout, Layout new_layout) const
143+
-> Result<Allocation, AllocError> {
144+
return DefaultInImpl<Allocator, alloc_::Global>::grow_zeroed(
145+
pointer, old_layout, new_layout);
146+
}
147+
148+
auto shrink(void* pointer, Layout old_layout, Layout new_layout) const
149+
-> Result<Allocation, AllocError> {
150+
return DefaultInImpl<Allocator, alloc_::Global>::shrink(pointer, old_layout, new_layout);
151+
}
135152
};
136153

137154
namespace alloc

‎tests/main/alloc/module.cppm‎

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
export module rstd.tests.alloc_module;
2+
import rstd.alloc;
3+
4+
using namespace rstd::prelude;
5+
using rstd::alloc::Allocator;
6+
using rstd::alloc::Layout;
7+
8+
struct GlobalDynAllocation {
9+
ref<dyn<Allocator>> allocator = ::alloc::allocator_ref(::alloc::GLOBAL);
10+
Layout layout;
11+
void* pointer;
12+
13+
~GlobalDynAllocation() { allocator->deallocate(pointer, layout); }
14+
15+
auto aligned() const -> bool {
16+
return reinterpret_cast<rstd::uintptr_t>(pointer) % layout.align.to_primitive() == 0;
17+
}
18+
19+
auto bytes() const -> unsigned char* { return static_cast<unsigned char*>(pointer); }
20+
};
21+
22+
export auto global_dyn_resize() -> bool {
23+
auto allocator = ::alloc::allocator_ref(::alloc::GLOBAL);
24+
auto initial = Layout::from_size_align(usize(8), usize(64)).unwrap();
25+
auto result = allocator->allocate(initial);
26+
if (result.is_err()) return false;
27+
GlobalDynAllocation memory { allocator, initial, result.unwrap().pointer };
28+
if (! memory.aligned()) return false;
29+
for (unsigned i = 0; i < 8; ++i) memory.bytes()[i] = 0x5a;
30+
31+
auto larger = Layout::from_size_align(usize(16), usize(128)).unwrap();
32+
auto grown = allocator->grow(memory.pointer, memory.layout, larger);
33+
if (grown.is_err()) return false;
34+
memory.pointer = grown.unwrap().pointer;
35+
memory.layout = larger;
36+
if (! memory.aligned()) return false;
37+
for (unsigned i = 0; i < 8; ++i)
38+
if (memory.bytes()[i] != 0x5a) return false;
39+
for (unsigned i = 8; i < 16; ++i) memory.bytes()[i] = 0xa5;
40+
41+
auto zeroed_layout = Layout::from_size_align(usize(32), usize(256)).unwrap();
42+
auto zeroed = allocator->grow_zeroed(memory.pointer, memory.layout, zeroed_layout);
43+
if (zeroed.is_err()) return false;
44+
memory.pointer = zeroed.unwrap().pointer;
45+
memory.layout = zeroed_layout;
46+
if (! memory.aligned()) return false;
47+
for (unsigned i = 0; i < 32; ++i) {
48+
auto expected = i < 8 ? 0x5a : i < 16 ? 0xa5 : 0;
49+
if (memory.bytes()[i] != expected) return false;
50+
}
51+
52+
auto smaller = Layout::from_size_align(usize(4), usize(512)).unwrap();
53+
auto shrunk = allocator->shrink(memory.pointer, memory.layout, smaller);
54+
if (shrunk.is_err()) return false;
55+
memory.pointer = shrunk.unwrap().pointer;
56+
memory.layout = smaller;
57+
if (! memory.aligned()) return false;
58+
for (unsigned i = 0; i < 4; ++i)
59+
if (memory.bytes()[i] != 0x5a) return false;
60+
return true;
61+
}
62+
63+
export auto global_dyn_zeroed_and_empty() -> bool {
64+
auto allocator = ::alloc::allocator_ref(::alloc::GLOBAL);
65+
auto layout = Layout::from_size_align(usize(16), usize(64)).unwrap();
66+
auto result = allocator->allocate_zeroed(layout);
67+
if (result.is_err()) return false;
68+
GlobalDynAllocation memory { allocator, layout, result.unwrap().pointer };
69+
if (! memory.aligned()) return false;
70+
for (unsigned i = 0; i < 16; ++i)
71+
if (memory.bytes()[i] != 0) return false;
72+
73+
auto empty = Layout::from_size_align(usize(), usize(64)).unwrap();
74+
auto shrunk = allocator->shrink(memory.pointer, memory.layout, empty);
75+
if (shrunk.is_err()) return false;
76+
memory.pointer = shrunk.unwrap().pointer;
77+
memory.layout = empty;
78+
if (! memory.aligned() || memory.pointer == nullptr) return false;
79+
auto grown = allocator->grow_zeroed(memory.pointer, memory.layout, layout);
80+
if (grown.is_err()) return false;
81+
memory.pointer = grown.unwrap().pointer;
82+
memory.layout = layout;
83+
if (! memory.aligned()) return false;
84+
for (unsigned i = 0; i < 16; ++i)
85+
if (memory.bytes()[i] != 0) return false;
86+
87+
auto allocated = allocator->allocate(empty);
88+
if (allocated.is_err()) return false;
89+
GlobalDynAllocation empty_memory { allocator, empty, allocated.unwrap().pointer };
90+
return empty_memory.pointer != nullptr && empty_memory.aligned();
91+
}

‎tests/main/alloc/raw.cpp‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <rstd/test/gtest.hpp>
22
import rstd.alloc;
3+
import rstd.tests.alloc_module;
34

45
namespace
56
{
@@ -40,6 +41,14 @@ TEST(RawAlloc, ValueInitializesAndAcceptsNullDelete) {
4041
::alloc::raw_delete(constant);
4142
}
4243

44+
TEST(RawAlloc, GlobalDynResizeAcrossModules) {
45+
EXPECT_TRUE(global_dyn_resize());
46+
}
47+
48+
TEST(RawAlloc, GlobalDynZeroedAndEmptyAcrossModules) {
49+
EXPECT_TRUE(global_dyn_zeroed_and_empty());
50+
}
51+
4352
#if defined(__cpp_exceptions)
4453
TEST(RawAlloc, ConstructorFailureReleasesStorageWithoutDestruction) {
4554
struct Throws {

‎tests/main/lito.toml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ sources = [
5656
"hint.cpp",
5757
"alloc/rc.cpp",
5858
"alloc/raw.cpp",
59+
"alloc/module.cppm",
5960
"alloc/str.cpp",
6061
"alloc/boxed.cpp",
6162
"alloc/ownership.cpp",

0 commit comments

Comments
 (0)