1//===- MCJITMemoryManagerTest.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 "llvm/ExecutionEngine/SectionMemoryManager.h"
11#include "gtest/gtest.h"
12
13using namespace llvm;
14
15namespace {
16
17TEST(MCJITMemoryManagerTest, BasicAllocations) {
18  std::unique_ptr<SectionMemoryManager> MemMgr(new SectionMemoryManager());
19
20  uint8_t *code1 = MemMgr->allocateCodeSection(256, 0, 1, "");
21  uint8_t *data1 = MemMgr->allocateDataSection(256, 0, 2, "", true);
22  uint8_t *code2 = MemMgr->allocateCodeSection(256, 0, 3, "");
23  uint8_t *data2 = MemMgr->allocateDataSection(256, 0, 4, "", false);
24
25  EXPECT_NE((uint8_t*)nullptr, code1);
26  EXPECT_NE((uint8_t*)nullptr, code2);
27  EXPECT_NE((uint8_t*)nullptr, data1);
28  EXPECT_NE((uint8_t*)nullptr, data2);
29
30  // Initialize the data
31  for (unsigned i = 0; i < 256; ++i) {
32    code1[i] = 1;
33    code2[i] = 2;
34    data1[i] = 3;
35    data2[i] = 4;
36  }
37
38  // Verify the data (this is checking for overlaps in the addresses)
39  for (unsigned i = 0; i < 256; ++i) {
40    EXPECT_EQ(1, code1[i]);
41    EXPECT_EQ(2, code2[i]);
42    EXPECT_EQ(3, data1[i]);
43    EXPECT_EQ(4, data2[i]);
44  }
45
46  std::string Error;
47  EXPECT_FALSE(MemMgr->finalizeMemory(&Error));
48}
49
50TEST(MCJITMemoryManagerTest, LargeAllocations) {
51  std::unique_ptr<SectionMemoryManager> MemMgr(new SectionMemoryManager());
52
53  uint8_t *code1 = MemMgr->allocateCodeSection(0x100000, 0, 1, "");
54  uint8_t *data1 = MemMgr->allocateDataSection(0x100000, 0, 2, "", true);
55  uint8_t *code2 = MemMgr->allocateCodeSection(0x100000, 0, 3, "");
56  uint8_t *data2 = MemMgr->allocateDataSection(0x100000, 0, 4, "", false);
57
58  EXPECT_NE((uint8_t*)nullptr, code1);
59  EXPECT_NE((uint8_t*)nullptr, code2);
60  EXPECT_NE((uint8_t*)nullptr, data1);
61  EXPECT_NE((uint8_t*)nullptr, data2);
62
63  // Initialize the data
64  for (unsigned i = 0; i < 0x100000; ++i) {
65    code1[i] = 1;
66    code2[i] = 2;
67    data1[i] = 3;
68    data2[i] = 4;
69  }
70
71  // Verify the data (this is checking for overlaps in the addresses)
72  for (unsigned i = 0; i < 0x100000; ++i) {
73    EXPECT_EQ(1, code1[i]);
74    EXPECT_EQ(2, code2[i]);
75    EXPECT_EQ(3, data1[i]);
76    EXPECT_EQ(4, data2[i]);
77  }
78
79  std::string Error;
80  EXPECT_FALSE(MemMgr->finalizeMemory(&Error));
81}
82
83TEST(MCJITMemoryManagerTest, ManyAllocations) {
84  std::unique_ptr<SectionMemoryManager> MemMgr(new SectionMemoryManager());
85
86  uint8_t* code[10000];
87  uint8_t* data[10000];
88
89  for (unsigned i = 0; i < 10000; ++i) {
90    const bool isReadOnly = i % 2 == 0;
91
92    code[i] = MemMgr->allocateCodeSection(32, 0, 1, "");
93    data[i] = MemMgr->allocateDataSection(32, 0, 2, "", isReadOnly);
94
95    for (unsigned j = 0; j < 32; j++) {
96      code[i][j] = 1 + (i % 254);
97      data[i][j] = 2 + (i % 254);
98    }
99
100    EXPECT_NE((uint8_t *)nullptr, code[i]);
101    EXPECT_NE((uint8_t *)nullptr, data[i]);
102  }
103
104  // Verify the data (this is checking for overlaps in the addresses)
105  for (unsigned i = 0; i < 10000; ++i) {
106    for (unsigned j = 0; j < 32;j++ ) {
107      uint8_t ExpectedCode = 1 + (i % 254);
108      uint8_t ExpectedData = 2 + (i % 254);
109      EXPECT_EQ(ExpectedCode, code[i][j]);
110      EXPECT_EQ(ExpectedData, data[i][j]);
111    }
112  }
113
114  std::string Error;
115  EXPECT_FALSE(MemMgr->finalizeMemory(&Error));
116}
117
118TEST(MCJITMemoryManagerTest, ManyVariedAllocations) {
119  std::unique_ptr<SectionMemoryManager> MemMgr(new SectionMemoryManager());
120
121  uint8_t* code[10000];
122  uint8_t* data[10000];
123
124  for (unsigned i = 0; i < 10000; ++i) {
125    uintptr_t CodeSize = i % 16 + 1;
126    uintptr_t DataSize = i % 8 + 1;
127
128    bool isReadOnly = i % 3 == 0;
129    unsigned Align = 8 << (i % 4);
130
131    code[i] = MemMgr->allocateCodeSection(CodeSize, Align, i, "");
132    data[i] = MemMgr->allocateDataSection(DataSize, Align, i + 10000, "",
133                                          isReadOnly);
134
135    for (unsigned j = 0; j < CodeSize; j++) {
136      code[i][j] = 1 + (i % 254);
137    }
138
139    for (unsigned j = 0; j < DataSize; j++) {
140      data[i][j] = 2 + (i % 254);
141    }
142
143    EXPECT_NE((uint8_t *)nullptr, code[i]);
144    EXPECT_NE((uint8_t *)nullptr, data[i]);
145
146    uintptr_t CodeAlign = Align ? (uintptr_t)code[i] % Align : 0;
147    uintptr_t DataAlign = Align ? (uintptr_t)data[i] % Align : 0;
148
149    EXPECT_EQ((uintptr_t)0, CodeAlign);
150    EXPECT_EQ((uintptr_t)0, DataAlign);
151  }
152
153  for (unsigned i = 0; i < 10000; ++i) {
154    uintptr_t CodeSize = i % 16 + 1;
155    uintptr_t DataSize = i % 8 + 1;
156
157    for (unsigned j = 0; j < CodeSize; j++) {
158      uint8_t ExpectedCode = 1 + (i % 254);
159      EXPECT_EQ(ExpectedCode, code[i][j]);
160    }
161
162    for (unsigned j = 0; j < DataSize; j++) {
163      uint8_t ExpectedData = 2 + (i % 254);
164      EXPECT_EQ(ExpectedData, data[i][j]);
165    }
166  }
167}
168
169} // Namespace
170
171