-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathPageMap.cpp
99 lines (88 loc) · 2.54 KB
/
PageMap.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include "basetypes.h"
#include "PageMap.h"
#include "NativeCodeCache.h"
PageMap::PageMap()
{
memset(root.entries, 0, sizeof(Level1PageNode*) * NUM_ROOT_PAGENODE_ENTRIES);
}
PageMap::~PageMap()
{
for(uint32 nRoot = 0; nRoot < NUM_ROOT_PAGENODE_ENTRIES; nRoot++)
{
const Level1PageNode * const pL1 = root.entries[nRoot];
if(pL1)
{
for(uint32 nL1 = 0; nL1 < NUM_LEVEL1_PAGENODE_ENTRIES; nL1++)
{
NativeCodeCacheEntry * const pL2 = pL1->entries[nL1];
if(pL2)
{
delete [] pL2;
}
}
delete pL1;
}
}
}
NativeCodeCacheEntry *PageMap::AllocatePage(const uint32 address)
{
const uint32 rootIndex = address >> 23;
const uint32 l1Index = (address >> 10) & 0x1FFFUL;
Level1PageNode* pL1Node = root.entries[rootIndex];
if(!pL1Node)
{
pL1Node = new Level1PageNode;
memset(pL1Node->entries, 0, sizeof(NativeCodeCacheEntry*) * NUM_LEVEL1_PAGENODE_ENTRIES);
root.entries[rootIndex] = pL1Node;
}
NativeCodeCacheEntry* pL2Node = pL1Node->entries[l1Index];
if(!pL2Node)
{
pL2Node = new NativeCodeCacheEntry[NUM_LEVEL2_PAGENODE_ENTRIES];
//!! init_array((uint8*)pL2Node, NUM_LEVEL2_PAGENODE_ENTRIES * sizeof(NativeCodeCacheEntry));
for(uint32 i = 0; i < NUM_LEVEL2_PAGENODE_ENTRIES; i++)
{
pL2Node[i].virtualAddress = 1;
}
pL1Node->entries[l1Index] = pL2Node;
}
return pL2Node;
}
void PageMap::InvalidateEntry(const uint32 address)
{
const uint32 rootIndex = (address >> 23);
const Level1PageNode* const pL1Node = root.entries[rootIndex];
if(pL1Node)
{
const uint32 l1Index = (address >> 10) & 0x1FFFUL;
NativeCodeCacheEntry * const pL2Node = pL1Node->entries[l1Index];
{
if(pL2Node)
{
const uint32 l2Index = address & 0x3FFUL;
pL2Node[l2Index].virtualAddress = 1;
}
}
}
}
void PageMap::Invalidate(void)
{
for(uint32 rootIndex = 0; rootIndex < NUM_ROOT_PAGENODE_ENTRIES; rootIndex++)
{
if(root.entries[rootIndex])
{
const Level1PageNode * const pL1Node = root.entries[rootIndex];
for(uint32 l1Index = 0; l1Index < NUM_LEVEL1_PAGENODE_ENTRIES; l1Index++)
{
if(pL1Node->entries[l1Index])
{
NativeCodeCacheEntry * const pL2Node = pL1Node->entries[l1Index];
for(uint32 l2Index = 0; l2Index < NUM_LEVEL2_PAGENODE_ENTRIES; l2Index++)
{
pL2Node[l2Index].virtualAddress = 1;
}
}
}
}
}
}