blob: 1dc0b4752d06503ffe3d587ae0d699dc807b76ed (
plain)
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
|
// Copyright 2014 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <chrono>
#include "Common/CommonTypes.h"
#include "Common/Timer.h"
#include "Core/MemTools.h"
#include "Core/PowerPC/JitCommon/JitBase.h"
// include order is important
#include <gtest/gtest.h> // NOLINT
enum
{
#ifdef _WIN32
PAGE_GRAN = 0x10000
#else
PAGE_GRAN = 0x1000
#endif
};
class PageFaultFakeJit : public JitBase
{
public:
// CPUCoreBase methods
void Init() override {}
void Shutdown() override {}
void ClearCache() override {}
void Run() override {}
void SingleStep() override {}
const char *GetName() override { return nullptr; }
// JitBase methods
JitBaseBlockCache *GetBlockCache() override { return nullptr; }
void Jit(u32 em_address) override {}
const CommonAsmRoutinesBase *GetAsmRoutines() override { return nullptr; }
virtual bool HandleFault(uintptr_t access_address, SContext* ctx) override
{
m_pre_unprotect_time = std::chrono::high_resolution_clock::now();
UnWriteProtectMemory(m_data, PAGE_GRAN, /*allowExecute*/ false);
m_post_unprotect_time = std::chrono::high_resolution_clock::now();
return true;
}
void* m_data;
std::chrono::time_point<std::chrono::high_resolution_clock>
m_pre_unprotect_time, m_post_unprotect_time;
};
TEST(PageFault, PageFault)
{
EMM::InstallExceptionHandler();
void* data = AllocateMemoryPages(PAGE_GRAN);
EXPECT_NE(data, nullptr);
WriteProtectMemory(data, PAGE_GRAN, false);
PageFaultFakeJit pfjit;
jit = &pfjit;
pfjit.m_data = data;
auto start = std::chrono::high_resolution_clock::now();
*(volatile int*) data = 5;
auto end = std::chrono::high_resolution_clock::now();
#define AS_NS(diff) ((unsigned long long)std::chrono::duration_cast<std::chrono::nanoseconds>(diff).count())
EMM::UninstallExceptionHandler();
jit = nullptr;
printf("page fault timing:\n");
printf("start->HandleFault %llu ns\n", AS_NS(pfjit.m_pre_unprotect_time - start));
printf("UnWriteProtectMemory %llu ns\n", AS_NS(pfjit.m_post_unprotect_time - pfjit.m_pre_unprotect_time));
printf("HandleFault->end %llu ns\n", AS_NS(end - pfjit.m_post_unprotect_time));
printf("total %llu ns\n", AS_NS(end - start));
}
|