Fixing unittests on 32-bit Darwin, using 0x...ULL instead of 0x...U .
[oota-llvm.git] / unittests / ExecutionEngine / JIT / JITMemoryManagerTest.cpp
1 //===- JITMemoryManagerTest.cpp - Unit tests for the JIT memory manager ---===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "gtest/gtest.h"
11 #include "llvm/ADT/OwningPtr.h"
12 #include "llvm/ExecutionEngine/JITMemoryManager.h"
13 #include "llvm/DerivedTypes.h"
14 #include "llvm/Function.h"
15 #include "llvm/GlobalValue.h"
16
17 using namespace llvm;
18
19 namespace {
20
21 Function *makeFakeFunction() {
22   std::vector<const Type*> params;
23   const FunctionType *FTy = FunctionType::get(Type::VoidTy, params, false);
24   return Function::Create(FTy, GlobalValue::ExternalLinkage);
25 }
26
27 // Allocate three simple functions that fit in the initial slab.  This exercises
28 // the code in the case that we don't have to allocate more memory to store the
29 // function bodies.
30 TEST(JITMemoryManagerTest, NoAllocations) {
31   OwningPtr<JITMemoryManager> MemMgr(
32       JITMemoryManager::CreateDefaultMemManager());
33   uintptr_t size;
34   uint8_t *start;
35   std::string Error;
36
37   // Allocate the functions.
38   OwningPtr<Function> F1(makeFakeFunction());
39   size = 1024;
40   start = MemMgr->startFunctionBody(F1.get(), size);
41   memset(start, 0xFF, 1024);
42   MemMgr->endFunctionBody(F1.get(), start, start + 1024);
43   EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
44
45   OwningPtr<Function> F2(makeFakeFunction());
46   size = 1024;
47   start = MemMgr->startFunctionBody(F2.get(), size);
48   memset(start, 0xFF, 1024);
49   MemMgr->endFunctionBody(F2.get(), start, start + 1024);
50   EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
51
52   OwningPtr<Function> F3(makeFakeFunction());
53   size = 1024;
54   start = MemMgr->startFunctionBody(F3.get(), size);
55   memset(start, 0xFF, 1024);
56   MemMgr->endFunctionBody(F3.get(), start, start + 1024);
57   EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
58
59   // Deallocate them out of order, in case that matters.
60   MemMgr->deallocateMemForFunction(F2.get());
61   EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
62   MemMgr->deallocateMemForFunction(F1.get());
63   EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
64   MemMgr->deallocateMemForFunction(F3.get());
65   EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
66 }
67
68 // Make three large functions that take up most of the space in the slab.  Then
69 // try allocating three smaller functions that don't require additional slabs.
70 TEST(JITMemoryManagerTest, TestCodeAllocation) {
71   OwningPtr<JITMemoryManager> MemMgr(
72       JITMemoryManager::CreateDefaultMemManager());
73   uintptr_t size;
74   uint8_t *start;
75   std::string Error;
76
77   // Big functions are a little less than the largest block size.
78   const uintptr_t smallFuncSize = 1024;
79   const uintptr_t bigFuncSize = (MemMgr->GetDefaultCodeSlabSize() -
80                                  smallFuncSize * 2);
81
82   // Allocate big functions
83   OwningPtr<Function> F1(makeFakeFunction());
84   size = bigFuncSize;
85   start = MemMgr->startFunctionBody(F1.get(), size);
86   ASSERT_LE(bigFuncSize, size);
87   memset(start, 0xFF, bigFuncSize);
88   MemMgr->endFunctionBody(F1.get(), start, start + bigFuncSize);
89   EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
90
91   OwningPtr<Function> F2(makeFakeFunction());
92   size = bigFuncSize;
93   start = MemMgr->startFunctionBody(F2.get(), size);
94   ASSERT_LE(bigFuncSize, size);
95   memset(start, 0xFF, bigFuncSize);
96   MemMgr->endFunctionBody(F2.get(), start, start + bigFuncSize);
97   EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
98
99   OwningPtr<Function> F3(makeFakeFunction());
100   size = bigFuncSize;
101   start = MemMgr->startFunctionBody(F3.get(), size);
102   ASSERT_LE(bigFuncSize, size);
103   memset(start, 0xFF, bigFuncSize);
104   MemMgr->endFunctionBody(F3.get(), start, start + bigFuncSize);
105   EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
106
107   // Check that each large function took it's own slab.
108   EXPECT_EQ(3U, MemMgr->GetNumCodeSlabs());
109
110   // Allocate small functions
111   OwningPtr<Function> F4(makeFakeFunction());
112   size = smallFuncSize;
113   start = MemMgr->startFunctionBody(F4.get(), size);
114   ASSERT_LE(smallFuncSize, size);
115   memset(start, 0xFF, smallFuncSize);
116   MemMgr->endFunctionBody(F4.get(), start, start + smallFuncSize);
117   EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
118
119   OwningPtr<Function> F5(makeFakeFunction());
120   size = smallFuncSize;
121   start = MemMgr->startFunctionBody(F5.get(), size);
122   ASSERT_LE(smallFuncSize, size);
123   memset(start, 0xFF, smallFuncSize);
124   MemMgr->endFunctionBody(F5.get(), start, start + smallFuncSize);
125   EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
126
127   OwningPtr<Function> F6(makeFakeFunction());
128   size = smallFuncSize;
129   start = MemMgr->startFunctionBody(F6.get(), size);
130   ASSERT_LE(smallFuncSize, size);
131   memset(start, 0xFF, smallFuncSize);
132   MemMgr->endFunctionBody(F6.get(), start, start + smallFuncSize);
133   EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
134
135   // Check that the small functions didn't allocate any new slabs.
136   EXPECT_EQ(3U, MemMgr->GetNumCodeSlabs());
137
138   // Deallocate them out of order, in case that matters.
139   MemMgr->deallocateMemForFunction(F2.get());
140   EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
141   MemMgr->deallocateMemForFunction(F1.get());
142   EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
143   MemMgr->deallocateMemForFunction(F4.get());
144   EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
145   MemMgr->deallocateMemForFunction(F3.get());
146   EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
147   MemMgr->deallocateMemForFunction(F5.get());
148   EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
149   MemMgr->deallocateMemForFunction(F6.get());
150   EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
151 }
152
153 // Allocate five global ints of varying widths and alignment, and check their
154 // alignment and overlap.
155 TEST(JITMemoryManagerTest, TestSmallGlobalInts) {
156   OwningPtr<JITMemoryManager> MemMgr(
157       JITMemoryManager::CreateDefaultMemManager());
158   uint8_t  *a = (uint8_t *)MemMgr->allocateGlobal(8,  0);
159   uint16_t *b = (uint16_t*)MemMgr->allocateGlobal(16, 2);
160   uint32_t *c = (uint32_t*)MemMgr->allocateGlobal(32, 4);
161   uint64_t *d = (uint64_t*)MemMgr->allocateGlobal(64, 8);
162
163   // Check the alignment.
164   EXPECT_EQ(0U, ((uintptr_t)b) & 0x1);
165   EXPECT_EQ(0U, ((uintptr_t)c) & 0x3);
166   EXPECT_EQ(0U, ((uintptr_t)d) & 0x7);
167
168   // Initialize them each one at a time and make sure they don't overlap.
169   *a = 0xff;
170   *b = 0U;
171   *c = 0U;
172   *d = 0U;
173   EXPECT_EQ(0xffU, *a);
174   EXPECT_EQ(0U, *b);
175   EXPECT_EQ(0U, *c);
176   EXPECT_EQ(0U, *d);
177   *a = 0U;
178   *b = 0xffffU;
179   EXPECT_EQ(0U, *a);
180   EXPECT_EQ(0xffffU, *b);
181   EXPECT_EQ(0U, *c);
182   EXPECT_EQ(0U, *d);
183   *b = 0U;
184   *c = 0xffffffffU;
185   EXPECT_EQ(0U, *a);
186   EXPECT_EQ(0U, *b);
187   EXPECT_EQ(0xffffffffU, *c);
188   EXPECT_EQ(0U, *d);
189   *c = 0U;
190   *d = 0xffffffffffffffffULL;
191   EXPECT_EQ(0U, *a);
192   EXPECT_EQ(0U, *b);
193   EXPECT_EQ(0U, *c);
194   EXPECT_EQ(0xffffffffffffffffULL, *d);
195
196   // Make sure we didn't allocate any extra slabs for this tiny amount of data.
197   EXPECT_EQ(1U, MemMgr->GetNumDataSlabs());
198 }
199
200 // Allocate a small global, a big global, and a third global, and make sure we
201 // only use two slabs for that.
202 TEST(JITMemoryManagerTest, TestLargeGlobalArray) {
203   OwningPtr<JITMemoryManager> MemMgr(
204       JITMemoryManager::CreateDefaultMemManager());
205   size_t Size = 4 * MemMgr->GetDefaultDataSlabSize();
206   uint64_t *a = (uint64_t*)MemMgr->allocateGlobal(64, 8);
207   uint8_t *g = MemMgr->allocateGlobal(Size, 8);
208   uint64_t *b = (uint64_t*)MemMgr->allocateGlobal(64, 8);
209
210   // Check the alignment.
211   EXPECT_EQ(0U, ((uintptr_t)a) & 0x7);
212   EXPECT_EQ(0U, ((uintptr_t)g) & 0x7);
213   EXPECT_EQ(0U, ((uintptr_t)b) & 0x7);
214
215   // Initialize them to make sure we don't segfault and make sure they don't
216   // overlap.
217   memset(a, 0x1, 8);
218   memset(g, 0x2, Size);
219   memset(b, 0x3, 8);
220   EXPECT_EQ(0x0101010101010101ULL, *a);
221   // Just check the edges.
222   EXPECT_EQ(0x02U, g[0]);
223   EXPECT_EQ(0x02U, g[Size - 1]);
224   EXPECT_EQ(0x0303030303030303ULL, *b);
225
226   // Check the number of slabs.
227   EXPECT_EQ(2U, MemMgr->GetNumDataSlabs());
228 }
229
230 // Allocate lots of medium globals so that we can test moving the bump allocator
231 // to a new slab.
232 TEST(JITMemoryManagerTest, TestManyGlobals) {
233   OwningPtr<JITMemoryManager> MemMgr(
234       JITMemoryManager::CreateDefaultMemManager());
235   size_t SlabSize = MemMgr->GetDefaultDataSlabSize();
236   size_t Size = 128;
237   int Iters = (SlabSize / Size) + 1;
238
239   // We should start with one slab.
240   EXPECT_EQ(1U, MemMgr->GetNumDataSlabs());
241
242   // After allocating a bunch of globals, we should have two.
243   for (int I = 0; I < Iters; ++I)
244     MemMgr->allocateGlobal(Size, 8);
245   EXPECT_EQ(2U, MemMgr->GetNumDataSlabs());
246
247   // And after much more, we should have three.
248   for (int I = 0; I < Iters; ++I)
249     MemMgr->allocateGlobal(Size, 8);
250   EXPECT_EQ(3U, MemMgr->GetNumDataSlabs());
251 }
252
253 // Allocate lots of function stubs so that we can test moving the stub bump
254 // allocator to a new slab.
255 TEST(JITMemoryManagerTest, TestManyStubs) {
256   OwningPtr<JITMemoryManager> MemMgr(
257       JITMemoryManager::CreateDefaultMemManager());
258   size_t SlabSize = MemMgr->GetDefaultStubSlabSize();
259   size_t Size = 128;
260   int Iters = (SlabSize / Size) + 1;
261
262   // We should start with one slab.
263   EXPECT_EQ(1U, MemMgr->GetNumStubSlabs());
264
265   // After allocating a bunch of stubs, we should have two.
266   for (int I = 0; I < Iters; ++I)
267     MemMgr->allocateStub(NULL, Size, 8);
268   EXPECT_EQ(2U, MemMgr->GetNumStubSlabs());
269
270   // And after much more, we should have three.
271   for (int I = 0; I < Iters; ++I)
272     MemMgr->allocateStub(NULL, Size, 8);
273   EXPECT_EQ(3U, MemMgr->GetNumStubSlabs());
274 }
275
276 }